summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-08-25 16:58:20 -0700
committerJosh Stone <jistone@redhat.com>2009-08-25 17:22:59 -0700
commit54558065ee8428cfdc42135f151739fbc787d034 (patch)
tree62b73a76f5f134a7075f7e80e0c8952c3710a61b
parent3f46f8c2a94567956a1a722da6d13de84726c344 (diff)
downloadsystemtap-steved-54558065ee8428cfdc42135f151739fbc787d034.tar.gz
systemtap-steved-54558065ee8428cfdc42135f151739fbc787d034.tar.xz
systemtap-steved-54558065ee8428cfdc42135f151739fbc787d034.zip
Index mod_cu_function_cache_t by cu->addr
Rather than constructing a "module:cu" string all the time, we can just index the cache by the cu die's addr field. The addr will never change as long as the Dwarf object is still alive. This has a quite noticeable performance impact for scripts that iterate over lots of cus (like for syscall.*). * dwflpp.h (stap_map): Allow void* keys too. (mod_cu_function_cache_t): Index by the void* cu->addr. * dwflpp.cxx (dwflpp::iterate_over_functions): Index cu_function_cache by addr, and build the verbose strings manually when needed. (dwflpp::declaration_resolve): Index global_alias_cache by addr.
-rw-r--r--dwflpp.cxx23
-rw-r--r--dwflpp.h20
2 files changed, 25 insertions, 18 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index 8a02fc6a..f0bf7dcf 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -558,15 +558,15 @@ dwflpp::declaration_resolve(const char *name)
if (!name)
return NULL;
- string key = module_name + ":" + cu_name;
- cu_function_cache_t *v = global_alias_cache[key];
+ cu_function_cache_t *v = global_alias_cache[cu->addr];
if (v == 0) // need to build the cache, just once per encountered module/cu
{
v = new cu_function_cache_t;
- global_alias_cache[key] = v;
+ global_alias_cache[cu->addr] = v;
iterate_over_globals(global_alias_caching_callback, v);
if (sess.verbose > 4)
- clog << "global alias cache " << key << " size " << v->size() << endl;
+ clog << "global alias cache " << module_name << ":" << cu_name
+ << " size " << v->size() << endl;
}
// XXX: it may be desirable to search other modules' declarations
@@ -607,15 +607,15 @@ dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query *
assert (module);
assert (cu);
- string key = module_name + ":" + cu_name;
- cu_function_cache_t *v = cu_function_cache[key];
+ cu_function_cache_t *v = cu_function_cache[cu->addr];
if (v == 0)
{
v = new cu_function_cache_t;
- cu_function_cache[key] = v;
+ cu_function_cache[cu->addr] = v;
dwarf_getfuncs (cu, cu_function_caching_callback, v, 0);
if (sess.verbose > 4)
- clog << "function cache " << key << " size " << v->size() << endl;
+ clog << "function cache " << module_name << ":" << cu_name
+ << " size " << v->size() << endl;
mod_info->update_symtab(v);
}
@@ -624,7 +624,8 @@ dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query *
{
Dwarf_Die& die = it->second;
if (sess.verbose > 4)
- clog << "function cache " << key << " hit " << function << endl;
+ clog << "function cache " << module_name << ":" << cu_name
+ << " hit " << function << endl;
return (*callback)(& die, q);
}
else if (name_has_wildcard (function))
@@ -637,8 +638,8 @@ dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query *
if (function_name_matches_pattern (func_name, function))
{
if (sess.verbose > 4)
- clog << "function cache " << key << " match " << func_name << " vs "
- << function << endl;
+ clog << "function cache " << module_name << ":" << cu_name
+ << " match " << func_name << " vs " << function << endl;
rc = (*callback)(& die, q);
if (rc != DWARF_CB_OK) break;
diff --git a/dwflpp.h b/dwflpp.h
index d31d2219..1d6fe0c8 100644
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -45,19 +45,25 @@ enum info_status { info_unknown, info_present, info_absent };
#ifdef HAVE_TR1_UNORDERED_MAP
#include <tr1/unordered_map>
-template<class T> struct stap_map {
- typedef std::tr1::unordered_map<std::string, T> type;
+template<class K, class V> struct stap_map {
+ typedef std::tr1::unordered_map<K, V> type;
};
#else
#include <ext/hash_map>
-template<class T> struct stap_map {
- typedef __gnu_cxx::hash_map<std::string, T, stap_map> type;
- size_t operator() (const std::string& s) const
+template<class K, class V> struct stap_map {
+ typedef __gnu_cxx::hash_map<K, V, stap_map> type;
+ size_t operator() (std::string const& s) const
{ __gnu_cxx::hash<const char*> h; return h(s.c_str()); }
+ size_t operator() (void* const& p) const
+ { __gnu_cxx::hash<long> h; return h(reinterpret_cast<long>(p)); }
};
#endif
-typedef stap_map<Dwarf_Die>::type cu_function_cache_t; // function -> die
-typedef stap_map<cu_function_cache_t*>::type mod_cu_function_cache_t; // module:cu -> function -> die
+
+// function -> die
+typedef stap_map<std::string, Dwarf_Die>::type cu_function_cache_t;
+
+// cu die -> (function -> die)
+typedef stap_map<void*, cu_function_cache_t*>::type mod_cu_function_cache_t;
typedef std::vector<func_info> func_info_map_t;
typedef std::vector<inline_instance_info> inline_instance_map_t;