[11/19] Convert type copying to new hash table

Message ID 20230407-t-robin-hood-hash-v1-11-900d93ef1510@tromey.com
State New
Headers
Series Add hash table to gdbsupport |

Commit Message

Tom Tromey April 7, 2023, 3:25 p.m. UTC
  This converts the type copying code to use the new hash map.
---
 gdb/compile/compile-object-run.c |  4 +--
 gdb/extension-priv.h             |  3 +-
 gdb/extension.c                  |  3 +-
 gdb/extension.h                  |  4 ++-
 gdb/gdbtypes.c                   | 59 ++++------------------------------------
 gdb/gdbtypes.h                   |  7 ++---
 gdb/guile/guile-internal.h       |  2 +-
 gdb/guile/scm-type.c             |  9 +++---
 gdb/guile/scm-value.c            |  3 +-
 gdb/python/py-type.c             |  6 ++--
 gdb/python/py-value.c            |  3 +-
 gdb/python/python-internal.h     |  2 +-
 gdb/value.c                      | 17 ++++++------
 gdb/value.h                      |  4 +--
 14 files changed, 40 insertions(+), 86 deletions(-)
  

Patch

diff --git a/gdb/compile/compile-object-run.c b/gdb/compile/compile-object-run.c
index abdea4d371f..f18fa32d802 100644
--- a/gdb/compile/compile-object-run.c
+++ b/gdb/compile/compile-object-run.c
@@ -106,8 +106,8 @@  do_module_cleanup (void *arg, int registers_valid)
 static type *
 create_copied_type_recursive (objfile *objfile, type *func_type)
 {
-  htab_up copied_types = create_copied_types_hash ();
-  func_type = copy_type_recursive (func_type, copied_types.get ());
+  copied_types_hash_t copied_types;
+  func_type = copy_type_recursive (func_type, copied_types);
   return func_type;
 }
 
diff --git a/gdb/extension-priv.h b/gdb/extension-priv.h
index 3442302a0be..df19fefd14c 100644
--- a/gdb/extension-priv.h
+++ b/gdb/extension-priv.h
@@ -192,7 +192,8 @@  struct extension_language_ops
      COPIED_TYPES is used to prevent cycles / duplicates and is passed to
      preserve_one_value.  */
   void (*preserve_values) (const struct extension_language_defn *,
-			   struct objfile *objfile, htab_t copied_types);
+			   struct objfile *objfile,
+			   copied_types_hash_t &copied_types);
 
   /* Return non-zero if there is a stop condition for the breakpoint.
      This is used to implement the restriction that a breakpoint may have
diff --git a/gdb/extension.c b/gdb/extension.c
index 65f3bab32a7..779910ba8d8 100644
--- a/gdb/extension.c
+++ b/gdb/extension.c
@@ -560,7 +560,8 @@  apply_ext_lang_frame_filter (frame_info_ptr frame,
    preserve_one_value.  */
 
 void
-preserve_ext_lang_values (struct objfile *objfile, htab_t copied_types)
+preserve_ext_lang_values (struct objfile *objfile,
+			  copied_types_hash_t &copied_types)
 {
   for (const struct extension_language_defn *extlang : extension_languages)
     {
diff --git a/gdb/extension.h b/gdb/extension.h
index 2b0445133d3..3b9b504f2ef 100644
--- a/gdb/extension.h
+++ b/gdb/extension.h
@@ -23,6 +23,7 @@ 
 #include "mi/mi-cmds.h" /* For PRINT_NO_VALUES, etc.  */
 #include "gdbsupport/array-view.h"
 #include "gdbsupport/gdb_optional.h"
+#include "gdbtypes.h"
 
 struct breakpoint;
 struct command_line;
@@ -295,7 +296,8 @@  extern enum ext_lang_bt_status apply_ext_lang_frame_filter
    enum ext_lang_frame_args args_type,
    struct ui_out *out, int frame_low, int frame_high);
 
-extern void preserve_ext_lang_values (struct objfile *, htab_t copied_types);
+extern void preserve_ext_lang_values (struct objfile *,
+				      copied_types_hash_t &copied_types);
 
 extern const struct extension_language_defn *get_breakpoint_cond_ext_lang
   (struct breakpoint *b, enum extension_language skip_lang);
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index 6af59351b76..9f3b3cbd256 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -5461,46 +5461,6 @@  recursive_dump_type (struct type *type, int spaces)
     obstack_free (&dont_print_type_obstack, NULL);
 }
 
-/* Trivial helpers for the libiberty hash table, for mapping one
-   type to another.  */
-
-struct type_pair
-{
-  type_pair (struct type *old_, struct type *newobj_)
-    : old (old_), newobj (newobj_)
-  {}
-
-  struct type * const old, * const newobj;
-};
-
-static hashval_t
-type_pair_hash (const void *item)
-{
-  const struct type_pair *pair = (const struct type_pair *) item;
-
-  return htab_hash_pointer (pair->old);
-}
-
-static int
-type_pair_eq (const void *item_lhs, const void *item_rhs)
-{
-  const struct type_pair *lhs = (const struct type_pair *) item_lhs;
-  const struct type_pair *rhs = (const struct type_pair *) item_rhs;
-
-  return lhs->old == rhs->old;
-}
-
-/* Allocate the hash table used by copy_type_recursive to walk
-   types without duplicates.  */
-
-htab_up
-create_copied_types_hash ()
-{
-  return htab_up (htab_create_alloc (1, type_pair_hash, type_pair_eq,
-				     htab_delete_entry<type_pair>,
-				     xcalloc, xfree));
-}
-
 /* Recursively copy (deep copy) a dynamic attribute list of a type.  */
 
 static struct dynamic_prop_list *
@@ -5532,27 +5492,20 @@  copy_dynamic_prop_list (struct obstack *storage,
    it is not associated with OBJFILE.  */
 
 struct type *
-copy_type_recursive (struct type *type, htab_t copied_types)
+copy_type_recursive (struct type *type, copied_types_hash_t &copied_types)
 {
-  void **slot;
-  struct type *new_type;
-
   if (!type->is_objfile_owned ())
     return type;
 
-  struct type_pair pair (type, nullptr);
+  auto iter = copied_types.find (type);
+  if (iter != copied_types.end ())
+    return iter->second;
 
-  slot = htab_find_slot (copied_types, &pair, INSERT);
-  if (*slot != NULL)
-    return ((struct type_pair *) *slot)->newobj;
-
-  new_type = type_allocator (type->arch ()).new_type ();
+  struct type *new_type = type_allocator (type->arch ()).new_type ();
 
   /* We must add the new type to the hash table immediately, in case
      we encounter this type again during a recursive call below.  */
-  struct type_pair *stored = new type_pair (type, new_type);
-
-  *slot = stored;
+  copied_types.insert (type, new_type);
 
   /* Copy the common fields of types.  For the main type, we simply
      copy the entire thing and then update specific fields as needed.  */
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index b5cccb784b2..0c53c9d7203 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -44,10 +44,9 @@ 
    written such that they can be used as both rvalues and lvalues.
  */
 
-#include "hashtab.h"
 #include "gdbsupport/array-view.h"
-#include "gdbsupport/gdb-hashtab.h"
 #include "gdbsupport/gdb_optional.h"
+#include "gdbsupport/hash-table.h"
 #include "gdbsupport/offset-type.h"
 #include "gdbsupport/enum-flags.h"
 #include "gdbsupport/underlying.h"
@@ -2708,10 +2707,10 @@  extern int class_or_union_p (const struct type *);
 
 extern void maintenance_print_type (const char *, int);
 
-extern htab_up create_copied_types_hash ();
+typedef gdb::hash_map<type *, type *> copied_types_hash_t;
 
 extern struct type *copy_type_recursive (struct type *type,
-					 htab_t copied_types);
+					 copied_types_hash_t &copied_types);
 
 extern struct type *copy_type (const struct type *type);
 
diff --git a/gdb/guile/guile-internal.h b/gdb/guile/guile-internal.h
index b04ef17a5ad..e29e654de29 100644
--- a/gdb/guile/guile-internal.h
+++ b/gdb/guile/guile-internal.h
@@ -596,7 +596,7 @@  extern bool gdbscm_auto_load_enabled (const struct extension_language_defn *);
 
 extern void gdbscm_preserve_values
   (const struct extension_language_defn *,
-   struct objfile *, htab_t copied_types);
+   struct objfile *, copied_types_hash_t &copied_types);
 
 extern enum ext_lang_rc gdbscm_apply_val_pretty_printer
   (const struct extension_language_defn *,
diff --git a/gdb/guile/scm-type.c b/gdb/guile/scm-type.c
index 008e792cc34..a880a478ba7 100644
--- a/gdb/guile/scm-type.c
+++ b/gdb/guile/scm-type.c
@@ -95,8 +95,8 @@  struct tyscm_deleter
       return;
 
     gdb_assert (htab != nullptr);
-    htab_up copied_types = create_copied_types_hash ();
-    htab_traverse_noresize (htab, tyscm_copy_type_recursive, copied_types.get ());
+    copied_types_hash_t copied_types;
+    htab_traverse_noresize (htab, tyscm_copy_type_recursive, &copied_types);
     htab_delete (htab);
   }
 };
@@ -376,13 +376,12 @@  static int
 tyscm_copy_type_recursive (void **slot, void *info)
 {
   type_smob *t_smob = (type_smob *) *slot;
-  htab_t copied_types = (htab_t) info;
+  copied_types_hash_t *copied_types = (copied_types_hash_t *) info;
   htab_t htab;
   eqable_gdb_smob **new_slot;
   type_smob t_smob_for_lookup;
 
-  htab_empty (copied_types);
-  t_smob->type = copy_type_recursive (t_smob->type, copied_types);
+  t_smob->type = copy_type_recursive (t_smob->type, *copied_types);
 
   /* The eq?-hashtab that the type lived in is going away.
      Add the type to its new eq?-hashtab: Otherwise if/when the type is later
diff --git a/gdb/guile/scm-value.c b/gdb/guile/scm-value.c
index 32a9539b3e2..29f51aaf852 100644
--- a/gdb/guile/scm-value.c
+++ b/gdb/guile/scm-value.c
@@ -87,7 +87,8 @@  static SCM substitute_symbol;
 
 void
 gdbscm_preserve_values (const struct extension_language_defn *extlang,
-			struct objfile *objfile, htab_t copied_types)
+			struct objfile *objfile,
+			copied_types_hash_t &copied_types)
 {
   value_smob *iter;
 
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index b68ec8d2c92..a0efec61e17 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -1100,15 +1100,13 @@  struct typy_deleter
        operating on.  */
     gdbpy_enter enter_py;
 
-    htab_up copied_types = create_copied_types_hash ();
+    copied_types_hash_t copied_types;
 
     while (obj)
       {
 	type_object *next = obj->next;
 
-	htab_empty (copied_types.get ());
-
-	obj->type = copy_type_recursive (obj->type, copied_types.get ());
+	obj->type = copy_type_recursive (obj->type, copied_types);
 
 	obj->next = NULL;
 	obj->prev = NULL;
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 65384c781bc..1857649eb3c 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -224,7 +224,8 @@  valpy_init (PyObject *self, PyObject *args, PyObject *kwds)
    each.  */
 void
 gdbpy_preserve_values (const struct extension_language_defn *extlang,
-		       struct objfile *objfile, htab_t copied_types)
+		       struct objfile *objfile,
+		       copied_types_hash_t &copied_types)
 {
   value_object *iter;
 
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 258f5c42537..508dd2ef550 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -383,7 +383,7 @@  extern enum ext_lang_bt_status gdbpy_apply_frame_filter
    struct ui_out *out, int frame_low, int frame_high);
 extern void gdbpy_preserve_values (const struct extension_language_defn *,
 				   struct objfile *objfile,
-				   htab_t copied_types);
+				   copied_types_hash_t &copied_types);
 extern enum ext_lang_bp_stop gdbpy_breakpoint_cond_says_stop
   (const struct extension_language_defn *, struct breakpoint *);
 extern int gdbpy_breakpoint_has_cond (const struct extension_language_defn *,
diff --git a/gdb/value.c b/gdb/value.c
index eab1933b256..1243e4f5eea 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -2373,7 +2373,7 @@  add_internal_function (gdb::unique_xmalloc_ptr<char> &&name,
 }
 
 void
-value::preserve (struct objfile *objfile, htab_t copied_types)
+value::preserve (struct objfile *objfile, copied_types_hash_t &copied_types)
 {
   if (m_type->objfile_owner () == objfile)
     m_type = copy_type_recursive (m_type, copied_types);
@@ -2386,7 +2386,7 @@  value::preserve (struct objfile *objfile, htab_t copied_types)
 
 static void
 preserve_one_internalvar (struct internalvar *var, struct objfile *objfile,
-			  htab_t copied_types)
+			  copied_types_hash_t &copied_types)
 {
   switch (var->kind)
     {
@@ -2409,7 +2409,7 @@  preserve_one_internalvar (struct internalvar *var, struct objfile *objfile,
 
 static void
 preserve_one_varobj (struct varobj *varobj, struct objfile *objfile,
-		     htab_t copied_types)
+		     copied_types_hash_t &copied_types)
 {
   if (varobj->type->is_objfile_owned ()
       && varobj->type->objfile_owner () == objfile)
@@ -2433,22 +2433,21 @@  preserve_values (struct objfile *objfile)
 {
   /* Create the hash table.  We allocate on the objfile's obstack, since
      it is soon to be deleted.  */
-  htab_up copied_types = create_copied_types_hash ();
+  copied_types_hash_t copied_types;
 
   for (const value_ref_ptr &item : value_history)
-    item->preserve (objfile, copied_types.get ());
+    item->preserve (objfile, copied_types);
 
   for (auto &pair : internalvars)
-    preserve_one_internalvar (&pair.second, objfile, copied_types.get ());
+    preserve_one_internalvar (&pair.second, objfile, copied_types);
 
   /* For the remaining varobj, check that none has type owned by OBJFILE.  */
   all_root_varobjs ([&copied_types, objfile] (struct varobj *varobj)
     {
-      preserve_one_varobj (varobj, objfile,
-			   copied_types.get ());
+      preserve_one_varobj (varobj, objfile, copied_types);
     });
 
-  preserve_ext_lang_values (objfile, copied_types.get ());
+  preserve_ext_lang_values (objfile, copied_types);
 }
 
 static void
diff --git a/gdb/value.h b/gdb/value.h
index e13f92c397b..49c160b8532 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -24,12 +24,12 @@ 
 #include "extension.h"
 #include "gdbsupport/gdb_ref_ptr.h"
 #include "gmp-utils.h"
+#include "gdbtypes.h"
 
 struct block;
 struct expression;
 struct regcache;
 struct symbol;
-struct type;
 struct ui_file;
 struct language_defn;
 struct value_print_options;
@@ -563,7 +563,7 @@  struct value
 
   /* Update this value before discarding OBJFILE.  COPIED_TYPES is
      used to prevent cycles / duplicates.  */
-  void preserve (struct objfile *objfile, htab_t copied_types);
+  void preserve (struct objfile *objfile, copied_types_hash_t &copied_types);
 
   /* Unpack a bitfield of BITSIZE bits found at BITPOS in the object
      at VALADDR + EMBEDDEDOFFSET that has the type of DEST_VAL and