diff options
author | Josh Stone <jistone@redhat.com> | 2009-06-02 00:43:49 -0700 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2009-06-02 00:43:49 -0700 |
commit | c8ad068755e7424e767660f2c27cb3b1e2d5343d (patch) | |
tree | 8d927da0ab13dac41b24560b5e472d2fa9e13e8e | |
parent | 276465828851648edc5b56f762a0d100051c9e32 (diff) | |
download | systemtap-steved-c8ad068755e7424e767660f2c27cb3b1e2d5343d.tar.gz systemtap-steved-c8ad068755e7424e767660f2c27cb3b1e2d5343d.tar.xz systemtap-steved-c8ad068755e7424e767660f2c27cb3b1e2d5343d.zip |
Cache the last result of dwarf_getscopes
This one function accounted for ~30% of my callgrind profile of
"stap -l 'syscall.*'", even though it was only called ~1200 times. We
call dwarf_getscopes for each $target variable, with the same parameters
within a given probe. Since they're no nicely grouped, it's easy to
just cache the most recent call, and the next few calls will be a hit.
Overall this cuts the number of calls down to about 300, for an easy
speed gain.
-rw-r--r-- | dwflpp.cxx | 24 | ||||
-rw-r--r-- | dwflpp.h | 5 |
2 files changed, 27 insertions, 2 deletions
@@ -66,7 +66,8 @@ static string TOK_KERNEL("kernel"); dwflpp::dwflpp(systemtap_session & session, const string& user_module): sess(session), module(NULL), module_bias(0), mod_info(NULL), module_start(0), module_end(0), cu(NULL), dwfl(NULL), - module_dwarf(NULL), function(NULL), blacklist_enabled(false) + module_dwarf(NULL), function(NULL), blacklist_enabled(false), + pc_cached_scopes(0), num_cached_scopes(0), cached_scopes(NULL) { if (user_module.empty()) setup_kernel(); @@ -77,6 +78,7 @@ dwflpp::dwflpp(systemtap_session & session, const string& user_module): dwflpp::~dwflpp() { + free(cached_scopes); if (dwfl) dwfl_end(dwfl); } @@ -165,6 +167,9 @@ dwflpp::focus_on_cu(Dwarf_Die * c) // Reset existing pointers and names function_name.clear(); function = NULL; + + free(cached_scopes); + cached_scopes = NULL; } @@ -1341,7 +1346,7 @@ dwflpp::find_variable_and_frame_base (Dwarf_Die *scope_die, assert (cu); - nscopes = dwarf_getscopes (cu, pc, &scopes); + nscopes = dwarf_getscopes_cached (pc, &scopes); int sidx; // if pc and scope_die are disjoint then we need dwarf_getscopes_die for (sidx = 0; sidx < nscopes; sidx++) @@ -2383,4 +2388,19 @@ dwflpp::relocate_address(Dwarf_Addr addr, } +int +dwflpp::dwarf_getscopes_cached (Dwarf_Addr pc, Dwarf_Die **scopes) +{ + if (!cached_scopes || pc != pc_cached_scopes) + { + free(cached_scopes); + cached_scopes = NULL; + pc_cached_scopes = pc; + num_cached_scopes = dwarf_getscopes(cu, pc, &cached_scopes); + } + *scopes = cached_scopes; + return num_cached_scopes; +} + + /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ @@ -382,6 +382,11 @@ private: bool blacklist_enabled; 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); }; #endif // DWFLPP_H |