]> sourceware.org Git - systemtap.git/commitdiff
dwflpp: add CU line caching
authorJonathan Lebon <jlebon@redhat.com>
Wed, 16 Apr 2014 18:08:47 +0000 (14:08 -0400)
committerJonathan Lebon <jlebon@redhat.com>
Thu, 17 Apr 2014 21:42:37 +0000 (17:42 -0400)
The upcoming patches re-implementing iterate_over_srcfile_lines() will
depend on the use of CU lines in lineno order. Since dwarf_getsrclines()
outputs them in addr order, it greatly helps performance to cache the
sorted version.

dwflpp.cxx
dwflpp.h

index 9fe4f8988649efd73f105fb9dcd0cbea367be721..7a6e806a71d22d146836dda3d34dfd3fc0935b93 100644 (file)
@@ -110,6 +110,11 @@ dwflpp::~dwflpp()
   delete_map(global_alias_cache);
   delete_map(cu_die_parent_cache);
 
+  cu_lines_cache_t::iterator i;
+  for (i = cu_lines_cache.begin(); i != cu_lines_cache.end(); ++i)
+    delete_map(*i->second);
+  delete_map(cu_lines_cache);
+
   if (dwfl)
     dwfl_end(dwfl);
   // NB: don't "delete mod_info;", as that may be shared
@@ -1481,6 +1486,68 @@ dwflpp::iterate_over_plt<void>(void *object, void (*callback)(void*,
 }
 
 
+// Comparator function for sorting
+static bool
+compare_lines(Dwarf_Line* a, Dwarf_Line* b)
+{
+  if (a == b)
+    return false;
+
+  int lineno_a = safe_dwarf_lineno(a);
+  int lineno_b = safe_dwarf_lineno(b);
+  if (lineno_a == lineno_b)
+    return safe_dwarf_lineaddr(a) < safe_dwarf_lineaddr(b);
+  return lineno_a < lineno_b;
+}
+
+// Interface to CU lines cache sorted by lineno
+lines_t*
+dwflpp::get_cu_lines_sorted_by_lineno(const char *srcfile)
+{
+  assert(cu);
+
+  srcfile_lines_cache_t *srcfile_lines = cu_lines_cache[cu];
+  if (!srcfile_lines)
+    {
+      srcfile_lines = new srcfile_lines_cache_t();
+      cu_lines_cache[cu] = srcfile_lines;
+    }
+
+  lines_t *lines = (*srcfile_lines)[srcfile];
+  if (!lines)
+    {
+      size_t nlines_cu = 0;
+      Dwarf_Lines *lines_cu = NULL;
+      dwarf_assert("dwarf_getsrclines",
+                   dwarf_getsrclines(cu, &lines_cu, &nlines_cu));
+
+      lines = new lines_t();
+      (*srcfile_lines)[srcfile] = lines;
+
+      for (size_t i = 0; i < nlines_cu; i++)
+        {
+          Dwarf_Line *line = dwarf_onesrcline(lines_cu, i);
+          const char *linesrc = safe_dwarf_linesrc(line);
+          if (strcmp(srcfile, linesrc))
+            continue;
+          lines->push_back(line);
+        }
+
+      if (lines->size() > 1)
+        sort(lines->begin(), lines->end(), compare_lines);
+
+      if (sess.verbose > 3)
+        {
+          clog << "found the following lines for %s:" << endl;
+          lines_t::iterator i;
+          for (i  = lines->begin(); i != lines->end(); ++i)
+            cout << safe_dwarf_lineno(*i) << " = " << hex
+                 << safe_dwarf_lineaddr(*i) << dec << endl;
+        }
+    }
+  return lines;
+}
+
 template<> void
 dwflpp::iterate_over_srcfile_lines<void>(char const * srcfile,
                                          int linenos[2],
index 144acabd8e1b6cd0f67f51fb33b68fcf1b808fbf..4d61cd15367afacd68a12236c51a65b5b399bd7f 100644 (file)
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -74,6 +74,18 @@ typedef unordered_map<void*, Dwarf_Die> cu_die_parent_cache_t;
 // cu die -> (die -> parent die)
 typedef unordered_map<void*, cu_die_parent_cache_t*> mod_cu_die_parent_cache_t;
 
+// Dwarf_Line[] (sorted by lineno)
+typedef std::vector<Dwarf_Line*> lines_t;
+typedef std::pair<lines_t::iterator,
+                  lines_t::iterator>
+        lines_range_t;
+
+// srcfile -> Dwarf_Line[]
+typedef unordered_map<std::string, lines_t*> srcfile_lines_cache_t;
+
+// cu die -> (srcfile -> Dwarf_Line[])
+typedef unordered_map<void*, srcfile_lines_cache_t*> cu_lines_cache_t;
+
 typedef std::vector<func_info> func_info_map_t;
 typedef std::vector<inline_instance_info> inline_instance_map_t;
 
@@ -460,6 +472,9 @@ private:
   void cache_die_parents(cu_die_parent_cache_t* parents, Dwarf_Die* die);
   cu_die_parent_cache_t *get_die_parents();
 
+  // Cache for cu lines sorted by lineno
+  cu_lines_cache_t cu_lines_cache;
+
   Dwarf_Die* get_parent_scope(Dwarf_Die* die);
 
   /* The global alias cache is used to resolve any DIE found in a
@@ -513,6 +528,9 @@ private:
 
   static int mod_function_caching_callback (Dwarf_Die* func, cu_function_cache_t *v);
   static int cu_function_caching_callback (Dwarf_Die* func, cu_function_cache_t *v);
+
+  lines_t* get_cu_lines_sorted_by_lineno(const char *srcfile);
+
   static int external_function_cu_callback (Dwarf_Die* cu, external_function_query *efq);
   static int external_function_func_callback (Dwarf_Die* func, external_function_query *efq);
 
This page took 0.039248 seconds and 5 git commands to generate.