diff options
author | Josh Stone <jistone@redhat.com> | 2010-03-30 14:54:39 -0700 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2010-03-30 15:16:35 -0700 |
commit | 4df79aaf86a9b6dfbccc3c51946024a30ba43726 (patch) | |
tree | 970c39eac7b4d55337b82f1bf7ed0e05f6656d64 /dwflpp.h | |
parent | 5898b6e1087175bc85e35ba147334fe87e3d7d06 (diff) | |
download | systemtap-steved-4df79aaf86a9b6dfbccc3c51946024a30ba43726.tar.gz systemtap-steved-4df79aaf86a9b6dfbccc3c51946024a30ba43726.tar.xz systemtap-steved-4df79aaf86a9b6dfbccc3c51946024a30ba43726.zip |
Use a wider cache for simple function lookups
When we have many individual function lookups, like the nearly 1000 with
syscall.*, each one will iterate every CU in the module (M) and then do a
cache lookup in N entries. That's a thousand MlogN lookups.
We can instead keep the functions in a module-wide map, and then the
complexity is just a thousand logMN lookups.
Before:
$ ./run-stap -l 'syscall.**' --vp 01 >/dev/null
Pass 2: analyzed script: 793 probe(s), 11 function(s), 20 embed(s),
0 global(s) using 245872virt/147304res/78272shr kb,
in 1390usr/60sys/1448real ms.
After:
$ ./run-stap -l 'syscall.**' --vp 01 >/dev/null
Pass 2: analyzed script: 793 probe(s), 11 function(s), 20 embed(s),
0 global(s) using 246228virt/147616res/78276shr kb,
in 720usr/60sys/782real ms.
* dwflpp.cxx (dwflpp::iterate_single_function): Do a simple function
lookup based on a module-wide cache.
(dwflpp::mod_function_caching_callback): Helper for above.
* tapsets.cxx (dwarf_query::query_module_functions): Query a single
function from the module-wide cache.
(dwarf_query::query_module_dwarf): Use above for simple cases.
Diffstat (limited to 'dwflpp.h')
-rw-r--r-- | dwflpp.h | 11 |
1 files changed, 9 insertions, 2 deletions
@@ -63,6 +63,9 @@ typedef std::pair<cu_function_cache_t::iterator, // cu die -> (function -> die) typedef unordered_map<void*, cu_function_cache_t*> mod_cu_function_cache_t; +// module -> (function -> die) +typedef unordered_map<Dwarf*, cu_function_cache_t*> mod_function_cache_t; + // inline function die -> instance die[] typedef unordered_map<void*, std::vector<Dwarf_Die>*> cu_inl_function_cache_t; @@ -215,11 +218,12 @@ struct dwflpp Dwarf_Die *declaration_resolve(const char *name); Dwarf_Die *declaration_resolve_other_cus(const char *name); - mod_cu_function_cache_t cu_function_cache; - int iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query * q), base_query * q, const std::string& function); + int iterate_single_function (int (* callback)(Dwarf_Die * func, base_query * q), + base_query * q, const std::string& function); + void iterate_over_srcfile_lines (char const * srcfile, int lines[2], bool need_single_match, @@ -296,6 +300,8 @@ private: void setup_user(const std::vector<std::string>& modules, bool debuginfo_needed = true); module_cu_cache_t module_cu_cache; + mod_cu_function_cache_t cu_function_cache; + mod_function_cache_t mod_function_cache; std::set<void*> cu_inl_function_cache_done; // CUs that are already cached cu_inl_function_cache_t cu_inl_function_cache; @@ -322,6 +328,7 @@ private: int (* callback)(Dwarf_Die *, void *), void * data); + static int mod_function_caching_callback (Dwarf_Die* func, void *arg); static int cu_function_caching_callback (Dwarf_Die* func, void *arg); bool has_single_line_record (dwarf_query * q, char const * srcfile, int lineno); |