forked from Imagelibrary/binutils-gdb
Convert type copying to new hash table
This converts the type copying code to use the new hash map. Change-Id: I35f0a4946dcc5c5eb84820126cf716b600f3302f Co-Authored-By: Tom Tromey <tom@tromey.com> Approved-By: Tom Tromey <tom@tromey.com>
This commit is contained in:
committed by
Simon Marchi
parent
c4b9453529
commit
112f6d85fb
@@ -105,9 +105,9 @@ do_module_cleanup (void *arg, int registers_valid)
|
|||||||
static type *
|
static type *
|
||||||
create_copied_type_recursive (objfile *objfile, type *func_type)
|
create_copied_type_recursive (objfile *objfile, type *func_type)
|
||||||
{
|
{
|
||||||
htab_up copied_types = create_copied_types_hash ();
|
copied_types_hash_t copied_types;
|
||||||
func_type = copy_type_recursive (func_type, copied_types.get ());
|
|
||||||
return func_type;
|
return copy_type_recursive (func_type, copied_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform inferior call of MODULE. This function may throw an error.
|
/* Perform inferior call of MODULE. This function may throw an error.
|
||||||
|
|||||||
@@ -201,7 +201,8 @@ struct extension_language_ops
|
|||||||
COPIED_TYPES is used to prevent cycles / duplicates and is passed to
|
COPIED_TYPES is used to prevent cycles / duplicates and is passed to
|
||||||
preserve_one_value. */
|
preserve_one_value. */
|
||||||
void (*preserve_values) (const struct extension_language_defn *,
|
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.
|
/* Return non-zero if there is a stop condition for the breakpoint.
|
||||||
This is used to implement the restriction that a breakpoint may have
|
This is used to implement the restriction that a breakpoint may have
|
||||||
|
|||||||
@@ -563,7 +563,8 @@ apply_ext_lang_ptwrite_filter (btrace_thread_info *btinfo)
|
|||||||
preserve_one_value. */
|
preserve_one_value. */
|
||||||
|
|
||||||
void
|
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)
|
for (const struct extension_language_defn *extlang : extension_languages)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,8 +22,8 @@
|
|||||||
|
|
||||||
#include "mi/mi-cmds.h"
|
#include "mi/mi-cmds.h"
|
||||||
#include "gdbsupport/array-view.h"
|
#include "gdbsupport/array-view.h"
|
||||||
#include "hashtab.h"
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include "gdbtypes.h"
|
||||||
|
|
||||||
struct breakpoint;
|
struct breakpoint;
|
||||||
struct command_line;
|
struct command_line;
|
||||||
@@ -307,7 +307,8 @@ extern enum ext_lang_bt_status apply_ext_lang_frame_filter
|
|||||||
extern void apply_ext_lang_ptwrite_filter
|
extern void apply_ext_lang_ptwrite_filter
|
||||||
(struct btrace_thread_info *btinfo);
|
(struct btrace_thread_info *btinfo);
|
||||||
|
|
||||||
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
|
extern const struct extension_language_defn *get_breakpoint_cond_ext_lang
|
||||||
(struct breakpoint *b, enum extension_language skip_lang);
|
(struct breakpoint *b, enum extension_language skip_lang);
|
||||||
|
|||||||
@@ -5407,46 +5407,6 @@ recursive_dump_type (struct type *type, int spaces)
|
|||||||
obstack_free (&dont_print_type_obstack, NULL);
|
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. */
|
/* Recursively copy (deep copy) a dynamic attribute list of a type. */
|
||||||
|
|
||||||
static struct dynamic_prop_list *
|
static struct dynamic_prop_list *
|
||||||
@@ -5478,27 +5438,20 @@ copy_dynamic_prop_list (struct obstack *storage,
|
|||||||
it is not associated with OBJFILE. */
|
it is not associated with OBJFILE. */
|
||||||
|
|
||||||
struct type *
|
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 ())
|
if (!type->is_objfile_owned ())
|
||||||
return type;
|
return type;
|
||||||
|
|
||||||
struct type_pair pair (type, nullptr);
|
if (auto iter = copied_types.find (type);
|
||||||
|
iter != copied_types.end ())
|
||||||
|
return iter->second;
|
||||||
|
|
||||||
slot = htab_find_slot (copied_types, &pair, INSERT);
|
struct type *new_type = type_allocator (type->arch ()).new_type ();
|
||||||
if (*slot != NULL)
|
|
||||||
return ((struct type_pair *) *slot)->newobj;
|
|
||||||
|
|
||||||
new_type = type_allocator (type->arch ()).new_type ();
|
|
||||||
|
|
||||||
/* We must add the new type to the hash table immediately, in case
|
/* We must add the new type to the hash table immediately, in case
|
||||||
we encounter this type again during a recursive call below. */
|
we encounter this type again during a recursive call below. */
|
||||||
struct type_pair *stored = new type_pair (type, new_type);
|
copied_types.emplace (type, new_type);
|
||||||
|
|
||||||
*slot = stored;
|
|
||||||
|
|
||||||
/* Copy the common fields of types. For the main type, we simply
|
/* Copy the common fields of types. For the main type, we simply
|
||||||
copy the entire thing and then update specific fields as needed. */
|
copy the entire thing and then update specific fields as needed. */
|
||||||
|
|||||||
@@ -44,14 +44,13 @@
|
|||||||
written such that they can be used as both rvalues and lvalues.
|
written such that they can be used as both rvalues and lvalues.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hashtab.h"
|
|
||||||
#include "gdbsupport/array-view.h"
|
#include "gdbsupport/array-view.h"
|
||||||
#include "gdbsupport/gdb-hashtab.h"
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include "gdbsupport/enum-flags.h"
|
#include "gdbsupport/enum-flags.h"
|
||||||
#include "dwarf2.h"
|
#include "dwarf2.h"
|
||||||
#include "gdbsupport/gdb_obstack.h"
|
#include "gdbsupport/gdb_obstack.h"
|
||||||
#include "gmp-utils.h"
|
#include "gmp-utils.h"
|
||||||
|
#include "gdbsupport/unordered_map.h"
|
||||||
|
|
||||||
/* Forward declarations for prototypes. */
|
/* Forward declarations for prototypes. */
|
||||||
struct field;
|
struct field;
|
||||||
@@ -2785,10 +2784,10 @@ extern int class_or_union_p (const struct type *);
|
|||||||
|
|
||||||
extern void maintenance_print_type (const char *, int);
|
extern void maintenance_print_type (const char *, int);
|
||||||
|
|
||||||
extern htab_up create_copied_types_hash ();
|
using copied_types_hash_t = gdb::unordered_map<type *, type *>;
|
||||||
|
|
||||||
extern struct type *copy_type_recursive (struct type *type,
|
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);
|
extern struct type *copy_type (const struct type *type);
|
||||||
|
|
||||||
|
|||||||
@@ -603,7 +603,7 @@ extern bool gdbscm_auto_load_enabled (const struct extension_language_defn *);
|
|||||||
|
|
||||||
extern void gdbscm_preserve_values
|
extern void gdbscm_preserve_values
|
||||||
(const struct extension_language_defn *,
|
(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
|
extern enum ext_lang_rc gdbscm_apply_val_pretty_printer
|
||||||
(const struct extension_language_defn *,
|
(const struct extension_language_defn *,
|
||||||
|
|||||||
@@ -94,8 +94,8 @@ struct tyscm_deleter
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
gdb_assert (htab != nullptr);
|
gdb_assert (htab != nullptr);
|
||||||
htab_up copied_types = create_copied_types_hash ();
|
copied_types_hash_t copied_types;
|
||||||
htab_traverse_noresize (htab, tyscm_copy_type_recursive, copied_types.get ());
|
htab_traverse_noresize (htab, tyscm_copy_type_recursive, &copied_types);
|
||||||
htab_delete (htab);
|
htab_delete (htab);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -375,12 +375,11 @@ static int
|
|||||||
tyscm_copy_type_recursive (void **slot, void *info)
|
tyscm_copy_type_recursive (void **slot, void *info)
|
||||||
{
|
{
|
||||||
type_smob *t_smob = (type_smob *) *slot;
|
type_smob *t_smob = (type_smob *) *slot;
|
||||||
htab_t copied_types = (htab_t) info;
|
copied_types_hash_t &copied_types = *static_cast<copied_types_hash_t *> (info);
|
||||||
htab_t htab;
|
htab_t htab;
|
||||||
eqable_gdb_smob **new_slot;
|
eqable_gdb_smob **new_slot;
|
||||||
type_smob t_smob_for_lookup;
|
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.
|
/* The eq?-hashtab that the type lived in is going away.
|
||||||
|
|||||||
@@ -86,7 +86,8 @@ static SCM substitute_symbol;
|
|||||||
|
|
||||||
void
|
void
|
||||||
gdbscm_preserve_values (const struct extension_language_defn *extlang,
|
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;
|
value_smob *iter;
|
||||||
|
|
||||||
|
|||||||
@@ -1174,15 +1174,14 @@ struct typy_deleter
|
|||||||
operating on. */
|
operating on. */
|
||||||
gdbpy_enter enter_py;
|
gdbpy_enter enter_py;
|
||||||
|
|
||||||
htab_up copied_types = create_copied_types_hash ();
|
copied_types_hash_t copied_types;
|
||||||
|
|
||||||
while (obj)
|
while (obj)
|
||||||
{
|
{
|
||||||
type_object *next = obj->next;
|
type_object *next = obj->next;
|
||||||
|
|
||||||
htab_empty (copied_types.get ());
|
copied_types.clear ();
|
||||||
|
obj->type = copy_type_recursive (obj->type, copied_types);
|
||||||
obj->type = copy_type_recursive (obj->type, copied_types.get ());
|
|
||||||
|
|
||||||
obj->next = NULL;
|
obj->next = NULL;
|
||||||
obj->prev = NULL;
|
obj->prev = NULL;
|
||||||
|
|||||||
@@ -233,7 +233,8 @@ valpy_init (PyObject *self, PyObject *args, PyObject *kwds)
|
|||||||
each. */
|
each. */
|
||||||
void
|
void
|
||||||
gdbpy_preserve_values (const struct extension_language_defn *extlang,
|
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;
|
value_object *iter;
|
||||||
|
|
||||||
|
|||||||
@@ -474,7 +474,7 @@ extern enum ext_lang_bt_status gdbpy_apply_frame_filter
|
|||||||
struct ui_out *out, int frame_low, int frame_high);
|
struct ui_out *out, int frame_low, int frame_high);
|
||||||
extern void gdbpy_preserve_values (const struct extension_language_defn *,
|
extern void gdbpy_preserve_values (const struct extension_language_defn *,
|
||||||
struct objfile *objfile,
|
struct objfile *objfile,
|
||||||
htab_t copied_types);
|
copied_types_hash_t &copied_types);
|
||||||
extern enum ext_lang_bp_stop gdbpy_breakpoint_cond_says_stop
|
extern enum ext_lang_bp_stop gdbpy_breakpoint_cond_says_stop
|
||||||
(const struct extension_language_defn *, struct breakpoint *);
|
(const struct extension_language_defn *, struct breakpoint *);
|
||||||
extern int gdbpy_breakpoint_has_cond (const struct extension_language_defn *,
|
extern int gdbpy_breakpoint_has_cond (const struct extension_language_defn *,
|
||||||
|
|||||||
17
gdb/value.c
17
gdb/value.c
@@ -2468,7 +2468,7 @@ add_internal_function (gdb::unique_xmalloc_ptr<char> &&name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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)
|
if (m_type->objfile_owner () == objfile)
|
||||||
m_type = copy_type_recursive (m_type, copied_types);
|
m_type = copy_type_recursive (m_type, copied_types);
|
||||||
@@ -2481,7 +2481,7 @@ value::preserve (struct objfile *objfile, htab_t copied_types)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
preserve_one_internalvar (struct internalvar *var, struct objfile *objfile,
|
preserve_one_internalvar (struct internalvar *var, struct objfile *objfile,
|
||||||
htab_t copied_types)
|
copied_types_hash_t &copied_types)
|
||||||
{
|
{
|
||||||
switch (var->kind)
|
switch (var->kind)
|
||||||
{
|
{
|
||||||
@@ -2504,7 +2504,7 @@ preserve_one_internalvar (struct internalvar *var, struct objfile *objfile,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
preserve_one_varobj (struct varobj *varobj, struct objfile *objfile,
|
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 ()
|
if (varobj->type->is_objfile_owned ()
|
||||||
&& varobj->type->objfile_owner () == objfile)
|
&& varobj->type->objfile_owner () == objfile)
|
||||||
@@ -2528,22 +2528,21 @@ preserve_values (struct objfile *objfile)
|
|||||||
{
|
{
|
||||||
/* Create the hash table. We allocate on the objfile's obstack, since
|
/* Create the hash table. We allocate on the objfile's obstack, since
|
||||||
it is soon to be deleted. */
|
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)
|
for (const value_ref_ptr &item : value_history)
|
||||||
item->preserve (objfile, copied_types.get ());
|
item->preserve (objfile, copied_types);
|
||||||
|
|
||||||
for (auto &pair : internalvars)
|
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. */
|
/* For the remaining varobj, check that none has type owned by OBJFILE. */
|
||||||
all_root_varobjs ([&copied_types, objfile] (struct varobj *varobj)
|
all_root_varobjs ([&copied_types, objfile] (struct varobj *varobj)
|
||||||
{
|
{
|
||||||
preserve_one_varobj (varobj, objfile,
|
preserve_one_varobj (varobj, objfile, copied_types);
|
||||||
copied_types.get ());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
preserve_ext_lang_values (objfile, copied_types.get ());
|
preserve_ext_lang_values (objfile, copied_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -24,12 +24,12 @@
|
|||||||
#include "extension.h"
|
#include "extension.h"
|
||||||
#include "gdbsupport/gdb_ref_ptr.h"
|
#include "gdbsupport/gdb_ref_ptr.h"
|
||||||
#include "gmp-utils.h"
|
#include "gmp-utils.h"
|
||||||
|
#include "gdbtypes.h"
|
||||||
|
|
||||||
struct block;
|
struct block;
|
||||||
struct expression;
|
struct expression;
|
||||||
struct regcache;
|
struct regcache;
|
||||||
struct symbol;
|
struct symbol;
|
||||||
struct type;
|
|
||||||
struct ui_file;
|
struct ui_file;
|
||||||
struct language_defn;
|
struct language_defn;
|
||||||
struct value_print_options;
|
struct value_print_options;
|
||||||
@@ -593,7 +593,7 @@ public:
|
|||||||
|
|
||||||
/* Update this value before discarding OBJFILE. COPIED_TYPES is
|
/* Update this value before discarding OBJFILE. COPIED_TYPES is
|
||||||
used to prevent cycles / duplicates. */
|
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
|
/* Unpack a bitfield of BITSIZE bits found at BITPOS in the object
|
||||||
at VALADDR + EMBEDDEDOFFSET that has the type of DEST_VAL and
|
at VALADDR + EMBEDDEDOFFSET that has the type of DEST_VAL and
|
||||||
|
|||||||
Reference in New Issue
Block a user