diff options
author | Simon Marchi <simon.marchi@efficios.com> | 2024-08-22 14:01:58 -0400 |
---|---|---|
committer | Simon Marchi <simon.marchi@efficios.com> | 2024-08-23 14:41:49 -0400 |
commit | ee8f65ec48cfadf10f2fb2191592bebd37dedd8a (patch) | |
tree | 4f49623ba66a8114c7b9f20a10d5b8586ace3ee6 | |
parent | 18784a7fe2bdbcbc5b03fe675ecbfe1e71085497 (diff) | |
download | gdb-users/simark/try-cxx-hash-table.zip gdb-users/simark/try-cxx-hash-table.tar.gz gdb-users/simark/try-cxx-hash-table.tar.bz2 |
Convert dwarf2_per_objfile::die_type_hash to new hash tableusers/simark/try-cxx-hash-table
Convert dwarf2_per_objfile::die_type_hash, which maps debug info
offsets to `type *`, to gdb::unordered_map.
Change-Id: I5c174af64ee46d38a465008090e812acf03704ec
-rw-r--r-- | gdb/dwarf2/read.c | 83 | ||||
-rw-r--r-- | gdb/dwarf2/read.h | 40 |
2 files changed, 43 insertions, 80 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 227ad19..e38a244 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -21653,52 +21653,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. @@ -21722,8 +21676,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; @@ -21779,24 +21731,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; } @@ -21808,19 +21749,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 40e1f55..c9ef4c7 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -627,6 +627,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<dwarf2_per_cu_data *> () (key.per_cu) + + std::hash<sect_offset> () (key.offset)); + } +}; + /* Collection of data recorded per objfile. This hangs off of dwarf2_objfile_data_key. @@ -701,10 +721,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<per_cu_and_offset, type *, per_cu_and_offset_hash> + die_type_hash; /* Table containing line_header indexed by offset and offset_in_dwz. */ htab_up line_header_hash; |