diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/dwarf2/read-debug-names.c | 5 | ||||
-rw-r--r-- | gdb/dwarf2/read-gdb-index.c | 2 | ||||
-rw-r--r-- | gdb/dwarf2/read.c | 189 | ||||
-rw-r--r-- | gdb/dwarf2/read.h | 21 |
4 files changed, 60 insertions, 157 deletions
diff --git a/gdb/dwarf2/read-debug-names.c b/gdb/dwarf2/read-debug-names.c index 8c265dd..edac713 100644 --- a/gdb/dwarf2/read-debug-names.c +++ b/gdb/dwarf2/read-debug-names.c @@ -424,13 +424,12 @@ cooked_index_worker_debug_names::do_reading () exceptions.push_back (std::move (exc)); } - dwarf2_per_bfd *per_bfd = m_per_objfile->per_bfd; - per_bfd->quick_file_names_table - = create_quick_file_names_table (per_bfd->all_units.size ()); m_results.emplace_back (nullptr, complaint_handler.release (), std::move (exceptions), parent_map ()); + + dwarf2_per_bfd *per_bfd = m_per_objfile->per_bfd; cooked_index *table = (gdb::checked_static_cast<cooked_index *> (per_bfd->index_table.get ())); diff --git a/gdb/dwarf2/read-gdb-index.c b/gdb/dwarf2/read-gdb-index.c index f6c73d0..3439163 100644 --- a/gdb/dwarf2/read-gdb-index.c +++ b/gdb/dwarf2/read-gdb-index.c @@ -1558,8 +1558,6 @@ dwarf2_read_gdb_index set_main_name_from_gdb_index (per_objfile, map.get ()); per_bfd->index_table = std::move (map); - per_bfd->quick_file_names_table = - create_quick_file_names_table (per_bfd->all_units.size ()); return true; } diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 5075839..68bba49 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -270,6 +270,8 @@ struct loclists_rnglists_header struct stmt_list_hash { + bool operator== (const stmt_list_hash &other) const noexcept; + /* The DWO unit this table is from or NULL if there is none. */ struct dwo_unit *dwo_unit; @@ -284,12 +286,8 @@ struct stmt_list_hash struct type_unit_group { - /* The data used to construct the hash key. */ - struct stmt_list_hash hash {}; }; -using type_unit_group_up = std::unique_ptr<type_unit_group>; - /* These sections are what may appear in a (real or virtual) DWO file. */ struct dwo_sections @@ -1535,9 +1533,6 @@ dwarf2_per_bfd::start_reading (dwarf_scanner_base_up new_table) line_header when we're done and don't need to record it here. */ struct quick_file_names { - /* The data used to construct the hash key. */ - struct stmt_list_hash hash; - /* The number of entries in file_names, real_names. */ unsigned int num_file_names; @@ -1579,64 +1574,34 @@ struct readnow_functions : public dwarf2_base_index_functions } }; -/* Utility hash function for a stmt_list_hash. */ - -static hashval_t -hash_stmt_list_entry (const struct stmt_list_hash *stmt_list_hash) -{ - hashval_t v = 0; - - if (stmt_list_hash->dwo_unit != NULL) - v += (uintptr_t) stmt_list_hash->dwo_unit->dwo_file; - v += to_underlying (stmt_list_hash->line_sect_off); - return v; -} - -/* Utility equality function for a stmt_list_hash. */ +/* See read.h. */ -static int -eq_stmt_list_entry (const struct stmt_list_hash *lhs, - const struct stmt_list_hash *rhs) +std::uint64_t +stmt_list_hash_hash::operator() (const stmt_list_hash &key) const noexcept { - if ((lhs->dwo_unit != NULL) != (rhs->dwo_unit != NULL)) - return 0; - if (lhs->dwo_unit != NULL - && lhs->dwo_unit->dwo_file != rhs->dwo_unit->dwo_file) - return 0; - - return lhs->line_sect_off == rhs->line_sect_off; -} + std::uint64_t v = 0; -/* Hash function for a quick_file_names. */ + if (key.dwo_unit != nullptr) + v += ankerl::unordered_dense::hash<dwo_file *> () (key.dwo_unit->dwo_file); -static hashval_t -hash_file_name_entry (const void *e) -{ - const struct quick_file_names *file_data - = (const struct quick_file_names *) e; - - return hash_stmt_list_entry (&file_data->hash); + v += (ankerl::unordered_dense::hash<std::uint64_t> () + (to_underlying (key.line_sect_off))); + return v; } -/* Equality function for a quick_file_names. */ +/* See read.h. */ -static int -eq_file_name_entry (const void *a, const void *b) +bool +stmt_list_hash::operator== (const stmt_list_hash &rhs) const noexcept { - const struct quick_file_names *ea = (const struct quick_file_names *) a; - const struct quick_file_names *eb = (const struct quick_file_names *) b; - - return eq_stmt_list_entry (&ea->hash, &eb->hash); -} + if ((this->dwo_unit != nullptr) != (rhs.dwo_unit != nullptr)) + return false; -/* See read.h. */ + if (this->dwo_unit != nullptr + && this->dwo_unit->dwo_file != rhs.dwo_unit->dwo_file) + return false; -htab_up -create_quick_file_names_table (unsigned int nr_initial_entries) -{ - return htab_up (htab_create_alloc (nr_initial_entries, - hash_file_name_entry, eq_file_name_entry, - nullptr, xcalloc, xfree)); + return this->line_sect_off == rhs.line_sect_off; } /* Read in CU (dwarf2_cu object) for PER_CU in the context of PER_OBJFILE. This @@ -1759,9 +1724,7 @@ dw2_get_file_names_reader (dwarf2_cu *cu, die_info *comp_unit_die) { dwarf2_per_cu *this_cu = cu->per_cu; dwarf2_per_objfile *per_objfile = cu->per_objfile; - struct attribute *attr; - void **slot; - struct quick_file_names *qfn; + dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; gdb_assert (! this_cu->is_debug_types); @@ -1771,29 +1734,24 @@ dw2_get_file_names_reader (dwarf2_cu *cu, die_info *comp_unit_die) if (comp_unit_die->tag == DW_TAG_partial_unit) return; - slot = NULL; - line_header_up lh; - sect_offset line_offset {}; file_and_directory &fnd = find_file_and_directory (comp_unit_die, cu); + std::optional<stmt_list_hash> stmt_list_hash_key; + attribute *attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu); - attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu); if (attr != nullptr && attr->form_is_unsigned ()) { - struct quick_file_names find_entry; - - line_offset = (sect_offset) attr->as_unsigned (); + sect_offset line_offset = (sect_offset) attr->as_unsigned (); /* We may have already read in this line header (TU line header sharing). If we have we're done. */ - find_entry.hash.dwo_unit = cu->dwo_unit; - find_entry.hash.line_sect_off = line_offset; - slot = htab_find_slot (per_objfile->per_bfd->quick_file_names_table.get (), - &find_entry, INSERT); - if (*slot != NULL) + stmt_list_hash_key = {cu->dwo_unit, line_offset}; + + if (auto it = per_bfd->quick_file_names_table.find (*stmt_list_hash_key); + it != per_bfd->quick_file_names_table.end ()) { - this_cu->file_names = (struct quick_file_names *) *slot; + this_cu->file_names = it->second; return; } @@ -1806,12 +1764,11 @@ dw2_get_file_names_reader (dwarf2_cu *cu, die_info *comp_unit_die) else if (lh == nullptr) return; - qfn = XOBNEW (&per_objfile->per_bfd->obstack, struct quick_file_names); - qfn->hash.dwo_unit = cu->dwo_unit; - qfn->hash.line_sect_off = line_offset; + auto *qfn = XOBNEW (&per_bfd->obstack, quick_file_names); + /* There may not be a DW_AT_stmt_list. */ - if (slot != nullptr) - *slot = qfn; + if (stmt_list_hash_key.has_value ()) + per_bfd->quick_file_names_table.emplace (*stmt_list_hash_key, qfn); std::vector<const char *> include_names; if (lh != nullptr) @@ -1831,9 +1788,8 @@ dw2_get_file_names_reader (dwarf2_cu *cu, die_info *comp_unit_die) qfn->num_file_names = offset + include_names.size (); qfn->comp_dir = fnd.intern_comp_dir (per_objfile->objfile); - qfn->file_names = - XOBNEWVEC (&per_objfile->per_bfd->obstack, const char *, - qfn->num_file_names); + qfn->file_names + = XOBNEWVEC (&per_bfd->obstack, const char *, qfn->num_file_names); if (offset != 0) qfn->file_names[0] = per_objfile->objfile->intern (fnd.get_name ()); @@ -2348,9 +2304,6 @@ dwarf2_initialize_objfile (struct objfile *objfile, dwarf_read_debug_printf ("readnow requested"); create_all_units (per_objfile); - per_bfd->quick_file_names_table - = create_quick_file_names_table (per_bfd->all_units.size ()); - objfile->qf.emplace_front (new readnow_functions); } /* Was a GDB index already read when we processed an objfile sharing @@ -3320,56 +3273,12 @@ cutu_reader::cutu_reader (dwarf2_per_cu *this_cu, together. A future step could be to put the types in the same symtab as the CU the types ultimately came from. */ -static hashval_t -hash_type_unit_group (const void *item) -{ - const struct type_unit_group *tu_group - = (const struct type_unit_group *) item; - - return hash_stmt_list_entry (&tu_group->hash); -} - -static int -eq_type_unit_group (const void *item_lhs, const void *item_rhs) -{ - const struct type_unit_group *lhs = (const struct type_unit_group *) item_lhs; - const struct type_unit_group *rhs = (const struct type_unit_group *) item_rhs; - - return eq_stmt_list_entry (&lhs->hash, &rhs->hash); -} - -/* Allocate a hash table for type unit groups. */ - -static htab_up -allocate_type_unit_groups_table () -{ - return htab_up (htab_create_alloc (3, - hash_type_unit_group, - eq_type_unit_group, - htab_delete_entry<type_unit_group>, - xcalloc, xfree)); -} - /* Type units that don't have DW_AT_stmt_list are grouped into their own partial symtabs. We combine several TUs per psymtab to not let the size of any one psymtab grow too big. */ #define NO_STMT_LIST_TYPE_UNIT_PSYMTAB (1 << 31) #define NO_STMT_LIST_TYPE_UNIT_PSYMTAB_SIZE 10 -/* Helper routine for get_type_unit_group. - Create the type_unit_group object used to hold one or more TUs. */ - -static type_unit_group_up -create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct) -{ - auto tu_group = std::make_unique<type_unit_group> (); - - tu_group->hash.dwo_unit = cu->dwo_unit; - tu_group->hash.line_sect_off = line_offset_struct; - - return tu_group; -} - /* Look up the type_unit_group for type unit CU, and create it if necessary. STMT_LIST is a DW_AT_stmt_list attribute. */ @@ -3377,14 +3286,9 @@ static struct type_unit_group * get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list) { dwarf2_per_objfile *per_objfile = cu->per_objfile; + dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; struct tu_stats *tu_stats = &per_objfile->per_bfd->tu_stats; - struct type_unit_group *tu_group; - void **slot; unsigned int line_offset; - struct type_unit_group type_unit_group_for_lookup; - - if (per_objfile->per_bfd->type_unit_groups == NULL) - per_objfile->per_bfd->type_unit_groups = allocate_type_unit_groups_table (); /* Do we need to create a new group, or can we use an existing one? */ @@ -3406,21 +3310,16 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list) ++tu_stats->nr_stmt_less_type_units; } - type_unit_group_for_lookup.hash.dwo_unit = cu->dwo_unit; - type_unit_group_for_lookup.hash.line_sect_off = (sect_offset) line_offset; - slot = htab_find_slot (per_objfile->per_bfd->type_unit_groups.get (), - &type_unit_group_for_lookup, INSERT); - if (*slot == nullptr) + stmt_list_hash key {cu->dwo_unit, static_cast<sect_offset> (line_offset)}; + auto [it, inserted] = per_bfd->type_unit_groups.emplace (key, nullptr); + + if (inserted) { - sect_offset line_offset_struct = (sect_offset) line_offset; - auto grp = create_type_unit_group (cu, line_offset_struct); - *slot = grp.release (); + (*it).second = std::make_unique<type_unit_group> (); ++tu_stats->nr_symtabs; } - tu_group = (struct type_unit_group *) *slot; - gdb_assert (tu_group != nullptr); - return tu_group; + return it->second.get (); } /* Subroutine of dwarf2_build_psymtabs_hard to simplify it. @@ -3526,7 +3425,7 @@ build_type_psymtabs (dwarf2_per_objfile *per_objfile, sect_offset abbrev_offset; /* It's up to the caller to not call us multiple times. */ - gdb_assert (per_objfile->per_bfd->type_unit_groups == NULL); + gdb_assert (per_objfile->per_bfd->type_unit_groups.empty ()); if (per_objfile->per_bfd->all_type_units.size () == 0) return; @@ -3781,8 +3680,6 @@ cooked_index_worker_debug_info::do_reading () create_all_units (m_per_objfile); build_type_psymtabs (m_per_objfile, &m_index_storage); - per_bfd->quick_file_names_table - = create_quick_file_names_table (per_bfd->all_units.size ()); if (!per_bfd->debug_aranges.empty ()) read_addrmap_from_aranges (m_per_objfile, &per_bfd->debug_aranges, m_index_storage.get_addrmap (), diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index 164c313..44fd7e9 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -467,6 +467,17 @@ struct dwp_file; using dwp_file_up = std::unique_ptr<dwp_file>; +struct stmt_list_hash; + +struct stmt_list_hash_hash +{ + using is_avalanching = void; + + std::uint64_t operator() (const stmt_list_hash &key) const noexcept; +}; + +using type_unit_group_up = std::unique_ptr<type_unit_group>; + /* Some DWARF data can be shared across objfiles who share the same BFD, this data is stored in this object. @@ -605,7 +616,8 @@ public: /* Table of struct type_unit_group objects. The hash key is the DW_AT_stmt_list value. */ - htab_up type_unit_groups; + gdb::unordered_map<stmt_list_hash, type_unit_group_up, stmt_list_hash_hash> + type_unit_groups; /* Set of signatured_types, used to look up by signature. */ signatured_type_set signatured_types; @@ -644,7 +656,8 @@ public: sorted all the TUs into "type unit groups", grouped by their DW_AT_stmt_list value. Therefore the only sharing done here is with a CU and its associated TU group if there is one. */ - htab_up quick_file_names_table; + gdb::unordered_map<stmt_list_hash, quick_file_names *, stmt_list_hash_hash> + quick_file_names_table; /* The CUs we recently read. */ std::vector<dwarf2_per_cu *> just_read_cus; @@ -1194,10 +1207,6 @@ extern void finalize_all_units (dwarf2_per_bfd *per_bfd); extern void create_all_units (dwarf2_per_objfile *per_objfile); -/* Create a quick_file_names hash table. */ - -extern htab_up create_quick_file_names_table (unsigned int nr_initial_entries); - /* Find the base address of the compilation unit for range lists and location lists. It will normally be specified by DW_AT_low_pc. In DWARF-3 draft 4, the base address could be overridden by |