]> sourceware.org Git - libabigail.git/commitdiff
dwarf-reader,corpus: Use interned string to lookup corpus interfaces by ID.
authorDodji Seketeli <dodji@redhat.com>
Fri, 12 Jan 2024 11:53:41 +0000 (12:53 +0100)
committerDodji Seketeli <dodji@redhat.com>
Mon, 12 Feb 2024 16:49:25 +0000 (17:49 +0100)
This patch speeds up the lookup of a function or variable using the
function/variable ID.  This patch is in preparation of many more
function lookup made during ABIXML emitting by patches coming up in
the future.

* include/abg-corpus.h (corpus::lookup_functions): Take an
interned_string instead of an std::string.  Add an overload for
const char* string too, for debugging purposes.
* src/abg-corpus-priv.h (istr_fn_ptr_set_map_type)
(istr_var_ptr_map_type): Define new typedefs.
(corpus::exported_decls_builder::priv::{id_fns_map_,
id_var_map_}): Use the new istr_fn_ptr_set_map_type and
istr_var_ptr_map_type types for these data members.
(corpus::exported_decls_builder::priv::{id_fns_map, id_var_map,
add_fn_to_id_fns_map, var_id_is_in_id_var_map, add_var_to_map,
add_var_to_exported}): Adjust.
(corpus::priv::lookup_functions): Declare new member function.
* src/abg-corpus.cc
(corpus::exported_decls_builder::maybe_add_var_to_exported_vars): Adjust.
(corpus::priv::lookup_functions): Define new member function.  The
code here comes from the code that was in
corpus::lookup_functions.  This is a factorization of
corpus::lookup_functions.
(corpus::lookup_functions): Take an interned_string instead of the
previous.  Factorize the code that was here into the new
corpus::priv::lookup_functions.
* src/abg-dwarf-reader.cc
(reader::symbol_already_belongs_to_a_function): Adjust the call to
corpus::lookup_functions to use an interned_string.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
include/abg-corpus.h
src/abg-corpus-priv.h
src/abg-corpus.cc
src/abg-dwarf-reader.cc

index 6de251deee21feb07a4cc7b7e98d57da4ef295b4..aafa3a1f9aad80d84ea04e147a3bb960ef39c21a 100644 (file)
@@ -219,7 +219,10 @@ public:
   get_functions() const;
 
   const std::unordered_set<function_decl*>*
-  lookup_functions(const string& id) const;
+  lookup_functions(const interned_string& id) const;
+
+  const std::unordered_set<function_decl*>*
+  lookup_functions(const char* id) const;
 
   void
   sort_functions();
index 412db377dd835109cce0e0019739743ccb716432..6908142ec3ea9115c45418393912260016f9d5d5 100644 (file)
@@ -19,6 +19,7 @@
 #include "abg-regex.h"
 #include "abg-sptr-utils.h"
 #include "abg-symtab-reader.h"
+#include "abg-interned-str.h"
 
 namespace abigail
 {
@@ -46,10 +47,22 @@ typedef unordered_map<string, vector<function_decl*> > str_fn_ptrs_map_type;
 typedef unordered_map<string, std::unordered_set<function_decl*> >
 str_fn_ptr_set_map_type;
 
+/// Convenience typedef for a hash map which key is an interned_string
+/// and which data is a set of abigail::ir::function_decl*
+typedef unordered_map<interned_string,
+                     std::unordered_set<function_decl*>,
+                     hash_interned_string> istr_fn_ptr_set_map_type;
+
 /// Convenience typedef for a hash map which key is a string and
 /// which data is an abigail::ir::var_decl*.
 typedef unordered_map<string, var_decl*> str_var_ptr_map_type;
 
+/// Convenience typedef for a hash map which key is an interned_string
+/// and which data is an abigail::ir::var_decl*.
+typedef unordered_map<interned_string,
+                     var_decl*,
+                     hash_interned_string> istr_var_ptr_map_type;
+
 /// The type of the private data of @ref
 /// corpus::exported_decls_builder type.
 class corpus::exported_decls_builder::priv
@@ -69,8 +82,8 @@ class corpus::exported_decls_builder::priv
   // template parameters of the second instantiation are just typedefs
   // of the first instantiation, for instance.  So there can be cases
   // where one ID appertains to more than one function.
-  str_fn_ptr_set_map_type      id_fns_map_;
-  str_var_ptr_map_type id_var_map_;
+  istr_fn_ptr_set_map_type     id_fns_map_;
+  istr_var_ptr_map_type        id_var_map_;
   strings_type&        fns_suppress_regexps_;
   regex_t_sptrs_type   compiled_fns_suppress_regexp_;
   strings_type&        vars_suppress_regexps_;
@@ -203,7 +216,7 @@ public:
   ///
   /// @return a map which key is a string and which data is a pointer
   /// to a function.
-  const str_fn_ptr_set_map_type&
+  const istr_fn_ptr_set_map_type&
   id_fns_map() const
   {return id_fns_map_;}
 
@@ -216,7 +229,7 @@ public:
   ///
   /// @return a map which key is a string and which data is a pointer
   /// to a function.
-  str_fn_ptr_set_map_type&
+  istr_fn_ptr_set_map_type&
   id_fns_map()
   {return id_fns_map_;}
 
@@ -229,7 +242,7 @@ public:
   ///
   /// @return a map which key is a string and which data is a pointer
   /// to a function.
-  const str_var_ptr_map_type&
+  const istr_var_ptr_map_type&
   id_var_map() const
   {return id_var_map_;}
 
@@ -242,7 +255,7 @@ public:
   ///
   /// @return a map which key is a string and which data is a pointer
   /// to a function.
-  str_var_ptr_map_type&
+  istr_var_ptr_map_type&
   id_var_map()
   {return id_var_map_;}
 
@@ -274,10 +287,10 @@ public:
   /// @return the pointer to the vector of functions with ID @p fn_id,
   /// or nil if no function with that ID exists.
   std::unordered_set<function_decl*>*
-  fn_id_is_in_id_fns_map(const string& fn_id)
+  fn_id_is_in_id_fns_map(const interned_string& fn_id)
   {
-    str_fn_ptr_set_map_type& m = id_fns_map();
-    str_fn_ptr_set_map_type::iterator i = m.find(fn_id);
+    istr_fn_ptr_set_map_type& m = id_fns_map();
+    auto i = m.find(fn_id);
     if (i == m.end())
       return 0;
     return &i->second;
@@ -295,7 +308,7 @@ public:
   std::unordered_set<function_decl*>*
   fn_id_is_in_id_fns_map(const function_decl* fn)
   {
-    string fn_id = fn->get_id();
+    interned_string fn_id = fn->get_id();
     return fn_id_is_in_id_fns_map(fn_id);
   }
 
@@ -389,7 +402,7 @@ public:
       return;
 
     // First associate the function id to the function.
-    string fn_id = fn->get_id();
+    interned_string fn_id = fn->get_id();
     std::unordered_set<function_decl*>* fns = fn_id_is_in_id_fns_map(fn_id);
     if (!fns)
       fns = &(id_fns_map()[fn_id] = std::unordered_set<function_decl*>());
@@ -424,10 +437,10 @@ public:
   /// @return true iff the variable designated by @p fn_id is present
   /// in the set of exported variables.
   bool
-  var_id_is_in_id_var_map(const string& var_id) const
+  var_id_is_in_id_var_map(const interned_string& var_id) const
   {
-    const str_var_ptr_map_type& m = id_var_map();
-    str_var_ptr_map_type::const_iterator i = m.find(var_id);
+    const istr_var_ptr_map_type& m = id_var_map();
+    auto i = m.find(var_id);
     return i != m.end();
   }
 
@@ -440,7 +453,7 @@ public:
   {
     if (var)
       {
-       const string& var_id = get_id(*var);
+       const interned_string& var_id = get_id(*var);
        id_var_map()[var_id] = var;
       }
   }
@@ -464,7 +477,7 @@ public:
   void
   add_var_to_exported(const var_decl* var)
   {
-    const string& id = get_id(*var);
+    const interned_string& id = get_id(*var);
     if (!var_id_is_in_id_var_map(id))
       {
        vars_.push_back(const_cast<var_decl*>(var));
@@ -813,6 +826,9 @@ public:
   unordered_set<interned_string, hash_interned_string>*
   get_public_types_pretty_representations();
 
+  std::unordered_set<function_decl*>*
+  lookup_functions(const interned_string& id);
+
   ~priv();
 }; // end struct corpus::priv
 
index 4a4cb8bc0d6eef8adcecb4c76d065db369a3ed6e..2a904079867cefd2588ddf5802f5f674eac5ee68 100644 (file)
@@ -184,7 +184,7 @@ corpus::exported_decls_builder::maybe_add_var_to_exported_vars(const var_decl* v
   if (!var->get_is_in_public_symbol_table())
     return;
 
-  const string& var_id = priv_->get_id(*var);
+  const interned_string& var_id = priv_->get_id(*var);
   ABG_ASSERT(!var_id.empty());
 
   if (priv_->var_id_is_in_id_var_map(var_id))
@@ -630,6 +630,34 @@ corpus::priv::get_public_types_pretty_representations()
   return pub_type_pretty_reprs_;
 }
 
+/// Lookup the function which has a given function ID.
+///
+/// Note that there can have been several functions with the same ID.
+/// This is because debug info can declare the same function in
+/// several different translation units.  Normally, all these function
+/// should be equal.  But still, this function returns all these
+/// functions.
+///
+/// @param id the ID of the function to lookup.  This ID must be
+/// either the result of invoking function::get_id() of
+/// elf_symbol::get_id_string().
+///
+/// @return the set of functions which ID is @p id, or nil if no
+/// function with that ID was found.
+std::unordered_set<function_decl*>*
+corpus::priv::lookup_functions(const interned_string& id)
+{
+  exported_decls_builder_sptr &b = exported_decls_builder;
+  if (b)
+    {
+      auto i = b->priv_->id_fns_map_.find(id);
+      if (i == b->priv_->id_fns_map_.end())
+       return 0;
+      return &i->second;
+    }
+  return nullptr;
+}
+
 /// Destructor of the @ref corpus::priv type.
 corpus::priv::~priv()
 {
@@ -1335,16 +1363,20 @@ corpus::get_functions() const
 /// either the result of invoking function::get_id() of
 /// elf_symbol::get_id_string().
 ///
-/// @return the vector functions which ID is @p id, or nil if no
+/// @return the set of functions which ID is @p id, or nil if no
 /// function with that ID was found.
 const std::unordered_set<function_decl*>*
-corpus::lookup_functions(const string& id) const
+corpus::lookup_functions(const interned_string& id) const
+{return priv_->lookup_functions(id);}
+
+const std::unordered_set<function_decl*>*
+corpus::lookup_functions(const char* id) const
 {
-  exported_decls_builder_sptr b = get_exported_decls_builder();
-  auto i = b->priv_->id_fns_map_.find(id);
-  if (i == b->priv_->id_fns_map_.end())
-    return 0;
-  return &i->second;
+  if (!id)
+    return nullptr;
+
+  interned_string string_id = priv_->env.intern(id);
+  return lookup_functions(string_id);
 }
 
 /// Sort the set of functions exported by this corpus.
index dc491b937813e42071212d2ac1ceca51fc547cce..36c8eea6a1dfb29217181d10db7c29e1b37b722e 100644 (file)
@@ -4486,7 +4486,7 @@ public:
     if (!corp)
       return false;
 
-    string id = fn->get_id_string();
+    interned_string id = corp->get_environment().intern(fn->get_id_string());
 
     const std::unordered_set<function_decl*> *fns = corp->lookup_functions(id);
     if (!fns)
This page took 0.046176 seconds and 5 git commands to generate.