]> sourceware.org Git - systemtap.git/commitdiff
Cache the last result of dwarf_getscopes
authorJosh Stone <jistone@redhat.com>
Tue, 2 Jun 2009 07:43:49 +0000 (00:43 -0700)
committerJosh Stone <jistone@redhat.com>
Tue, 2 Jun 2009 07:43:49 +0000 (00:43 -0700)
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.

dwflpp.cxx
dwflpp.h

index 52981d3f5a7fde60a12198a70a1a5262a2c3a03b..6ca9780d38f0ad18f3df51ff890a7f4e1b575481 100644 (file)
@@ -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 : */
index 554e02d43eaaabd9f80942c08823f86bed5d94fe..314e75839e43d2aeb69c738445b65c6e5e787b5c 100644 (file)
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -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
This page took 0.036205 seconds and 5 git commands to generate.