From e1bb778eabc85d262e368fdd6fbcee57b02c1bba Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Mon, 4 Nov 2024 13:27:56 -0500 Subject: Convert dwarf2_per_objfile::die_type_hash to new hash table Convert dwarf2_per_objfile::die_type_hash, which maps debug info offsets to `type *`, to gdb::unordered_map. Change-Id: I5c174af64ee46d38a465008090e812acf03704ec Approved-By: Tom Tromey --- gdb/dwarf2/read.c | 83 +++++-------------------------------------------------- gdb/dwarf2/read.h | 40 ++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 80 deletions(-) (limited to 'gdb') diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 4be122f..3f78b96 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -22019,52 +22019,6 @@ dwarf2_per_objfile::~dwarf2_per_objfile () remove_all_cus (); } -/* A set of CU "per_cu" pointer, DIE offset, and GDB type pointer. - We store these in a hash table separate from the DIEs, and preserve them - when the DIEs are flushed out of cache. - - The CU "per_cu" pointer is needed because offset alone is not enough to - uniquely identify the type. A file may have multiple .debug_types sections, - or the type may come from a DWO file. Furthermore, while it's more logical - to use per_cu->section+offset, with Fission the section with the data is in - the DWO file but we don't know that section at the point we need it. - We have to use something in dwarf2_per_cu_data (or the pointer to it) - because we can enter the lookup routine, get_die_type_at_offset, from - outside this file, and thus won't necessarily have PER_CU->cu. - Fortunately, PER_CU is stable for the life of the objfile. */ - -struct dwarf2_per_cu_offset_and_type -{ - const struct dwarf2_per_cu_data *per_cu; - sect_offset sect_off; - struct type *type; -}; - -/* Hash function for a dwarf2_per_cu_offset_and_type. */ - -static hashval_t -per_cu_offset_and_type_hash (const void *item) -{ - const struct dwarf2_per_cu_offset_and_type *ofs - = (const struct dwarf2_per_cu_offset_and_type *) item; - - return (uintptr_t) ofs->per_cu + to_underlying (ofs->sect_off); -} - -/* Equality function for a dwarf2_per_cu_offset_and_type. */ - -static int -per_cu_offset_and_type_eq (const void *item_lhs, const void *item_rhs) -{ - const struct dwarf2_per_cu_offset_and_type *ofs_lhs - = (const struct dwarf2_per_cu_offset_and_type *) item_lhs; - const struct dwarf2_per_cu_offset_and_type *ofs_rhs - = (const struct dwarf2_per_cu_offset_and_type *) item_rhs; - - return (ofs_lhs->per_cu == ofs_rhs->per_cu - && ofs_lhs->sect_off == ofs_rhs->sect_off); -} - /* Set the type associated with DIE to TYPE. Save it in CU's hash table if necessary. For convenience, return TYPE. @@ -22088,8 +22042,6 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu, bool skip_data_location) { dwarf2_per_objfile *per_objfile = cu->per_objfile; - struct dwarf2_per_cu_offset_and_type **slot, ofs; - struct objfile *objfile = per_objfile->objfile; struct attribute *attr; struct dynamic_prop prop; @@ -22145,24 +22097,13 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu, type->add_dyn_prop (DYN_PROP_DATA_LOCATION, prop); } - if (per_objfile->die_type_hash == NULL) - per_objfile->die_type_hash - = htab_up (htab_create_alloc (127, - per_cu_offset_and_type_hash, - per_cu_offset_and_type_eq, - NULL, xcalloc, xfree)); - - ofs.per_cu = cu->per_cu; - ofs.sect_off = die->sect_off; - ofs.type = type; - slot = (struct dwarf2_per_cu_offset_and_type **) - htab_find_slot (per_objfile->die_type_hash.get (), &ofs, INSERT); - if (*slot) + bool inserted + = per_objfile->die_type_hash.emplace + (per_cu_and_offset {cu->per_cu, die->sect_off}, type).second; + if (!inserted) complaint (_("A problem internal to GDB: DIE %s has type already set"), sect_offset_str (die->sect_off)); - *slot = XOBNEW (&objfile->objfile_obstack, - struct dwarf2_per_cu_offset_and_type); - **slot = ofs; + return type; } @@ -22174,19 +22115,9 @@ get_die_type_at_offset (sect_offset sect_off, dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile) { - struct dwarf2_per_cu_offset_and_type *slot, ofs; - - if (per_objfile->die_type_hash == NULL) - return NULL; + auto it = per_objfile->die_type_hash.find ({per_cu, sect_off}); - ofs.per_cu = per_cu; - ofs.sect_off = sect_off; - slot = ((struct dwarf2_per_cu_offset_and_type *) - htab_find (per_objfile->die_type_hash.get (), &ofs)); - if (slot) - return slot->type; - else - return NULL; + return it != per_objfile->die_type_hash.end () ? it->second : nullptr; } /* Look up the type for DIE in CU in die_type_hash, diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index e311309..1cc30eb 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -655,6 +655,26 @@ struct type_unit_group_unshareable struct symtab **symtabs = nullptr; }; +struct per_cu_and_offset +{ + dwarf2_per_cu_data *per_cu; + sect_offset offset; + + bool operator== (const per_cu_and_offset &other) const noexcept + { + return this->per_cu == other.per_cu && this->offset == other.offset; + } +}; + +struct per_cu_and_offset_hash +{ + std::uint64_t operator() (const per_cu_and_offset &key) const noexcept + { + return (std::hash () (key.per_cu) + + std::hash () (key.offset)); + } +}; + /* Collection of data recorded per objfile. This hangs off of dwarf2_objfile_data_key. @@ -729,10 +749,22 @@ struct dwarf2_per_objfile other objfiles backed by the same BFD. */ struct dwarf2_per_bfd *per_bfd; - /* Table mapping type DIEs to their struct type *. - This is nullptr if not allocated yet. - The mapping is done via (CU/TU + DIE offset) -> type. */ - htab_up die_type_hash; + /* A mapping of (CU "per_cu" pointer, DIE offset) to GDB type pointer. + + We store these in a hash table separate from the DIEs, and preserve them + when the DIEs are flushed out of cache. + + The CU "per_cu" pointer is needed because offset alone is not enough to + uniquely identify the type. A file may have multiple .debug_types sections, + or the type may come from a DWO file. Furthermore, while it's more logical + to use per_cu->section+offset, with Fission the section with the data is in + the DWO file but we don't know that section at the point we need it. + We have to use something in dwarf2_per_cu_data (or the pointer to it) + because we can enter the lookup routine, get_die_type_at_offset, from + outside this file, and thus won't necessarily have PER_CU->cu. + Fortunately, PER_CU is stable for the life of the objfile. */ + gdb::unordered_map + die_type_hash; /* Table containing line_header indexed by offset and offset_in_dwz. */ htab_up line_header_hash; -- cgit v1.1