]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
dwarf_output stats hack.
authorRoland McGrath <roland@redhat.com>
Mon, 14 Sep 2009 00:45:38 +0000 (17:45 -0700)
committerRoland McGrath <roland@redhat.com>
Wed, 16 Sep 2009 07:41:28 +0000 (00:41 -0700)
libdw/c++/dwarf
libdw/c++/dwarf_edit
libdw/c++/dwarf_output
libdw/c++/values.cc

index 0327e781195751c7d8b6e02d7d4e69e7ed8db701..0760942d510870e7ac9e59fb4e4ba49bc4b5d6e0 100644 (file)
@@ -508,6 +508,8 @@ namespace elfutils
       {
        return (uintptr_t) _m_die.addr;
       }
+
+      ::Dwarf_Off cost () const;
     };
 
     // Container for raw list of child DIEs, intended to be a compatible with
index 38a036e066729bacd7c225d950af6fd47fbde98d..9b093697868768ffa13c3cd7e31abf551df8d5cb 100644 (file)
@@ -252,6 +252,11 @@ namespace elfutils
        return identity ();
       }
 
+      inline ::Dwarf_Off cost () const
+      {
+       return 0;
+      }
+
       // Convenience entry point.
       inline pointer add_entry (int child_tag)
       {
index 434252d19493406f455927337680c1b6de107886..df2034915ace4a15df8e9960d42883fed87f3fb3 100644 (file)
@@ -385,6 +385,11 @@ namespace elfutils
       {
        return identity ();
       }
+
+      inline ::Dwarf_Off cost () const
+      {
+       return 0;
+      }
     };
 
     class attr_value
@@ -694,11 +699,13 @@ namespace elfutils
   {
     die_info_pair *_m_parent;
     std::queue<value::value_reference *> _m_refs;
+    ::Dwarf_Off _m_original_cost;
     std::bitset<2> _m_with_sibling;
     unsigned int _m_uses;
 
     inline die_info ()
-      : _m_parent (NULL), _m_refs (), _m_with_sibling (), _m_uses (0)
+      : _m_parent (NULL), _m_refs (),
+       _m_original_cost (0), _m_with_sibling (), _m_uses (0)
     {}
 
     inline ~die_info ()
@@ -932,7 +939,13 @@ namespace elfutils
       std::cout << std::dec << elt.second._m_uses
                << "\thash=" << std::hex << subr::hash_this (elt.first)
                << "\t(" << elt.second._m_with_sibling.to_string () << ")\t"
-               << to_string (elt.first) << "\n";
+               << std::dec << elt.second._m_original_cost;
+      if (elt.second._m_uses > 1)
+       std::cout << " ("
+                 << (double (elt.second._m_original_cost)
+                     / double (elt.second._m_uses - 1))
+                 << ")";
+      std::cout << "\t" << to_string (elt.first) << "\n";
     }
 
   public:
@@ -1289,6 +1302,7 @@ namespace elfutils
       : public value::value_dispatch
     {
       ::Dwarf_Off _m_offset; // XXX debugging only
+      ::Dwarf_Off _m_cost;   // For statistics only.
 
       // Set if we are building this in the copying walk right now.
       entry_copier *_m_building;
@@ -1666,6 +1680,8 @@ namespace elfutils
                      _m_building != NULL && refs_dangling);
 
        dump (false, true) << " final done\n";
+
+       _m_final->second._m_original_cost += _m_cost;
       }
 
       /* This is called from pending_entry::final when resolving
@@ -1757,6 +1773,7 @@ namespace elfutils
        if (unlikely (_m_in->_m_building != NULL))
          throw std::runtime_error ("detected cycle in logical DWARF tree");
        _m_in->_m_building = this;
+       _m_in->_m_cost = in.cost ();
       }
 
       // On destruction, we clear _m_building.
index b9e2730563da4444ba5be2e18bf28e0077812aba..8f97a98f79afe1953d449602bf2e9304bb27eaab 100644 (file)
@@ -688,3 +688,16 @@ namespace elfutils
     return dec_string (size (), "{", " line entries}");
   }
 };
+\f
+::Dwarf_Off
+dwarf::debug_info_entry::cost () const
+{
+  Dwarf_Die next;
+  int result = dwarf_siblingof (thisdie (), &next);
+  xif (result < 0);
+  if (result == 0)
+    return (const char *) next.addr - (const char *) _m_die.addr;
+  if (next.addr != NULL)
+    return (const char *) next.addr - (const char *) _m_die.addr + 1;
+  return _m_die.cu->end - dwarf_dieoffset (thisdie ());
+}