]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Optimize dwarf_output copying of strings and source_files with a copier cache.
authorRoland McGrath <roland@redhat.com>
Fri, 21 Aug 2009 09:15:30 +0000 (02:15 -0700)
committerRoland McGrath <roland@redhat.com>
Fri, 21 Aug 2009 09:35:30 +0000 (02:35 -0700)
libdw/ChangeLog
libdw/c++/dwarf
libdw/c++/dwarf_data
libdw/c++/dwarf_output

index 4c0531be1a7de830a1deafb1954e4ba30c2dca7d..96eebbf962c10f668744fbf83d7e911da0d8c1a2 100644 (file)
@@ -1,3 +1,10 @@
+2009-08-21  Roland McGrath  <roland@redhat.com>
+
+       * c++/dwarf (dwarf::source_file::identity): New method.
+       * c++/dwarf_data (dwarf_data::source_file::identity): Likewise.
+       * c++/dwarf_output (dwarf_output::copier): Cache input string
+       and source file pointers to short-circuit repeated full hashconsing.
+
 2009-08-20  Roland McGrath  <roland@redhat.com>
 
        * c++/values.cc (value_string): Fix constant-block case.
index 13257421db4721e802b492fbfa83645cd755df44..fe52c64aa25f34d7cbe75c13a5e459be75fe909b 100644 (file)
@@ -1119,6 +1119,13 @@ namespace elfutils
       {
        return !(*this == other);
       }
+
+      /* Return a value unique to us while we're in memory.
+        This is a stable pointer into the Dwarf_Files data.  */
+      inline uintptr_t identity () const
+      {
+       return (uintptr_t) name ();
+      }
     };
 
     // This describes the value of an attribute.
index b4de970de7a07d0dfbbab483fbba18e44f24423b..8ae8453eb175eaeb120008d77868701dbd68f105 100644 (file)
@@ -288,6 +288,12 @@ namespace elfutils
       {
        return !(*this == other);
       }
+
+      // Return a value unique to us while we're in memory.
+      inline uintptr_t identity () const
+      {
+       return (uintptr_t) this;
+      }
     };
 
     // This describes a CU's directory table, a simple array of strings.
index 488ba1e26fe89300a4b65235aff9403169afc6d9..46245f9d7d4f69f6a4b77e457f468c39a4990d72 100644 (file)
@@ -1989,16 +1989,73 @@ namespace elfutils
       return *_m_collector;
     }
 
+    /* We're likely to come across the same strings/identifiers and source
+       files many times in a copying run.  When they are the very same
+       pointers into the input dwarf object data, we can optimize the
+       ordinary string hash lookup in the value_set by caching the mapping
+       of input pointers to output values.  */
+    template<typename value_type>
+    struct string_cache
+    {
+      std::tr1::unordered_map<uintptr_t, const value_type *> _m_cache;
+
+      template<typename input>
+      inline const value_type *add (subr::value_set<value_type> &set,
+                                   uintptr_t key, const input &x)
+      {
+       const value_type *&cache = _m_cache[key];
+       if (cache == NULL)
+         cache = set.add (x);
+       return cache;
+      }
+
+      inline const value_type *add (subr::value_set<value_type> &set,
+                                   const char *x)
+      {
+       return add (set, (uintptr_t) x, x);
+      }
+
+      inline const value_type *add (subr::value_set<value_type> &set,
+                                   const std::string &x)
+      {
+       return add (set, (uintptr_t) &x, x);
+      }
+
+      template<typename input>
+      inline const value_type *add (subr::value_set<value_type> &set,
+                                   const input &x)
+      {
+       return set.add (x);
+      }
+    };
+
+    string_cache<value::value_string> _m_strings;
+    string_cache<value::value_identifier> _m_identifiers;
+
+    std::tr1::unordered_map<
+      uintptr_t, const value::value_source_file *> _m_source_file_cache;
+
+    template<typename input>
+    inline const value::value_source_file *add_source_file (int /*whatattr*/,
+                                                           const input &x)
+    {
+      const value::value_source_file *&cache
+       = _m_source_file_cache[x.identity ()];
+      if (cache == NULL)
+       cache = _m_collector->_m_source_file.add (x);
+      return cache;
+    }
+
     template<typename input>
     inline const value::value_string *add_string (const input &x)
     {
-      return _m_collector->_m_strings.add (x);
+      return _m_strings.add (_m_collector->_m_strings, x);
     }
 
     template<typename input>
     inline const value::value_string *add_identifier (const input &x)
     {
-      return _m_collector->_m_identifiers.add (x);
+      return _m_identifiers.add (_m_collector->_m_identifiers, x);
     }
 
     template<typename input>
@@ -2045,13 +2102,6 @@ namespace elfutils
       return _m_collector->_m_dwarf_const.add (x);
     }
 
-    template<typename input>
-    inline const value::value_source_file *add_source_file (int /*whatattr*/,
-                                                           const input &x)
-    {
-      return _m_collector->_m_source_file.add (x);
-    }
-
     template<typename input>
     inline const value::value_source_line *add_source_line (const input &x)
     {