[applied] Add environment::{get_type_id_from_pointer,get_canonical_type_from_type_id}

Message ID 87zgvy2kh3.fsf@redhat.com
State New
Headers
Series [applied] Add environment::{get_type_id_from_pointer,get_canonical_type_from_type_id} |

Commit Message

Dodji Seketeli June 10, 2021, 8:27 a.m. UTC
  Hello,

When debugging self comparison issues, once the abixml file is read
back into memory, I often want to get the type-id of an artifact that
was read from abixml or get the canonical type of an artifact which
type-id is known.

Part of that information is indirectly present in the data member
abigail::reader::reader_context::m_pointer_type_id_map after the
.typeid file is loaded from file into memory.  The problem is that the
instance of abigail::reader::reader_context is transient as it's
destroyed quickly after the abixml file is read.  We want it to stay
alive longer.  So this patch moves that data member into
abigail::environment instead, along with its accessors.  The patch
then adds the new member functions
environment::{get_type_id_from_pointer,get_canonical_type_from_type_id}
to get the type-id of an artifact de-serialized from abixml and the
canonical type of an artifact for which we now the type-id string.

	* include/abg-ir.h (environment::{get_pointer_type_id_map,
	get_type_id_from_pointer, get_canonical_type_from_type_id}):
	Declare new member functions.
	* src/abg-ir.cc (environment::{get_pointer_type_id_map,
	get_type_id_from_pointer, get_canonical_type_from_type_id}):
	Define member functions.
	(environment::priv::pointer_type_id_map_): Move
	this data member here from ...
	* src/abg-reader.cc (read_context::m_pointer_type_id_map):
	... here.
	(read_context::get_pointer_type_id_map): Remove this as it's now
	defined in environment::get_pointer_type_id_map.
	(read_context::maybe_check_abixml_canonical_type_stability):
	Adjust.
	(build_type): Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>

Applied to master.

---
 include/abg-ir.h  |  9 ++++++
 src/abg-ir.cc     | 70 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/abg-reader.cc | 36 +++++-------------------
 3 files changed, 85 insertions(+), 30 deletions(-)
  

Patch

diff --git a/include/abg-ir.h b/include/abg-ir.h
index e0638087..81984d6b 100644
--- a/include/abg-ir.h
+++ b/include/abg-ir.h
@@ -222,6 +222,15 @@  public:
 #ifdef WITH_DEBUG_SELF_COMPARISON
   unordered_map<string, uintptr_t>&
   get_type_id_canonical_type_map() const;
+
+  unordered_map<uintptr_t, string>&
+  get_pointer_type_id_map();
+
+  string
+  get_type_id_from_pointer(uintptr_t ptr);
+
+  uintptr_t
+  get_canonical_type_from_type_id(const char*);
 #endif
 
   friend class class_or_union;
diff --git a/src/abg-ir.cc b/src/abg-ir.cc
index bd4c6543..0f909b3d 100644
--- a/src/abg-ir.cc
+++ b/src/abg-ir.cc
@@ -2871,6 +2871,9 @@  struct environment::priv
   //   'abidw --debug-abidiff <binary>'.  It holds the set of mapping of
   // an abixml (canonical) type and its type-id.
   unordered_map<string, uintptr_t>	type_id_canonical_type_map_;
+  // Likewise.  It holds a map that associates the pointer to a type read from
+  // abixml and the type-id string it corresponds to.
+  unordered_map<uintptr_t, string>	pointer_type_id_map_;
 #endif
   bool					canonicalization_is_done_;
   bool					do_on_the_fly_canonicalization_;
@@ -3419,8 +3422,73 @@  environment::get_canonical_type(const char* name, unsigned index)
 unordered_map<string, uintptr_t>&
 environment::get_type_id_canonical_type_map() const
 {return priv_->type_id_canonical_type_map_;}
-#endif
 
+/// Getter of the map that associates the values of type pointers to
+/// their type-id strings.
+///
+/// Note that this map is populated at abixml reading time, (by
+/// build_type()) when a given XML element representing a type is
+/// read into a corresponding abigail::ir::type_base.
+///
+/// This is used only for the purpose of debugging the
+/// self-comparison process.  That is, when invoking "abidw
+/// --debug-abidiff".
+///
+/// @return the map that associates the values of type pointers to
+/// their type-id strings.
+unordered_map<uintptr_t, string>&
+environment::get_pointer_type_id_map()
+{return priv_->pointer_type_id_map_;}
+
+/// Getter of the type-id that corresponds to the value of a pointer
+/// to abigail::ir::type_base that was created from the abixml reader.
+///
+/// That value is retrieved from the map returned from
+/// environment::get_pointer_type_id_map().
+///
+/// That map is populated at abixml reading time, (by build_type())
+/// when a given XML element representing a type is read into a
+/// corresponding abigail::ir::type_base.
+///
+/// This is used only for the purpose of debugging the
+/// self-comparison process.  That is, when invoking "abidw
+/// --debug-abidiff".
+///
+/// @return the type-id strings that corresponds
+string
+environment::get_type_id_from_pointer(uintptr_t ptr)
+{
+  auto it = get_pointer_type_id_map().find(ptr);
+  if (it != get_pointer_type_id_map().end())
+    return it->second;
+  return "";
+}
+
+/// Getter of the canonical type of the artifact designated by a
+/// type-id.
+///
+/// That type-id was generated by the abixml writer at the emitting
+/// time of the abixml file.  The corresponding canonical type was
+/// stored in the map returned by
+/// environment::get_type_id_canonical_type_map().
+///
+/// This is useful for debugging purposes, especially in the context
+/// of the use of the command:
+///   'abidw --debug-abidiff <binary>'.
+///
+/// @return the set of abixml type-id and the pointer value of the
+/// (canonical) type it's associated to.
+uintptr_t
+environment::get_canonical_type_from_type_id(const char* type_id)
+{
+  if (!type_id)
+    return 0;
+  auto it = get_type_id_canonical_type_map().find(type_id);
+  if (it != get_type_id_canonical_type_map().end())
+    return it->second;
+  return 0;
+}
+#endif
 // </environment stuff>
 
 // <type_or_decl_base stuff>
diff --git a/src/abg-reader.cc b/src/abg-reader.cc
index 34136140..6d25b690 100644
--- a/src/abg-reader.cc
+++ b/src/abg-reader.cc
@@ -99,9 +99,6 @@  private:
   unordered_map<string, vector<type_base_sptr> >	m_types_map;
   unordered_map<string, shared_ptr<function_tdecl> >	m_fn_tmpl_map;
   unordered_map<string, shared_ptr<class_tdecl> >	m_class_tmpl_map;
-#ifdef WITH_DEBUG_SELF_COMPARISON
-  unordered_map<uintptr_t, string>			m_pointer_type_id_map;
-#endif
   vector<type_base_sptr>				m_types_to_canonicalize;
   string_xml_node_map					m_id_xml_node_map;
   xml_node_decl_base_sptr_map				m_xml_node_decl_map;
@@ -384,25 +381,6 @@  public:
     return i->second;
   }
 
-#ifdef WITH_DEBUG_SELF_COMPARISON
-  /// Getter of the map that associates the values of type pointers to
-  /// their type-id strings.
-  ///
-  /// Note that this map is populated at abixml reading time, (by
-  /// build_type()) when a given XML element representing a type is
-  /// read into a corresponding abigail::ir::type_base.
-  ///
-  /// This is used only for the purpose of debugging the
-  /// self-comparison process.  That is, when invoking "abidw
-  /// --debug-abidiff".
-  ///
-  /// @return the map that associates the values of type pointers to
-  /// their type-id strings.
-  unordered_map<uintptr_t, string>&
-  get_pointer_type_id_map()
-  {return m_pointer_type_id_map;}
-#endif
-
   /// Return the current lexical scope.
   scope_decl*
   get_cur_scope() const
@@ -844,12 +822,11 @@  public:
 
     // Let's get the type-id of this type as recorded in the
     // originating abixml file.
-    string type_id;
-    const auto i =
-      get_pointer_type_id_map().find(reinterpret_cast<uintptr_t>(t.get()));
-    if (i != get_pointer_type_id_map().end())
+    string type_id =
+      m_env->get_type_id_from_pointer(reinterpret_cast<uintptr_t>(t.get()));
+
+    if (!type_id.empty())
       {
-	type_id = i->second;
 	// Now let's get the canonical type that initially led to the
 	// serialization of a type with this type-id, when the abixml
 	// was being serialized.
@@ -5711,12 +5688,13 @@  build_type(read_context&	ctxt,
     }
 
 #ifdef WITH_DEBUG_SELF_COMPARISON
-  if (t && ctxt.get_environment()->self_comparison_debug_is_on())
+  environment *env = ctxt.get_environment();
+  if (t && env->self_comparison_debug_is_on())
     {
       string type_id;
       if (read_type_id_string(node, type_id))
 	// Let's store the type-id of this type pointer.
-	ctxt.get_pointer_type_id_map()[reinterpret_cast<uintptr_t>(t.get())] = type_id;
+	env->get_pointer_type_id_map()[reinterpret_cast<uintptr_t>(t.get())] = type_id;
     }
 #endif