[binutils-gdb] gdb/dwarf: use gdb::unordered_map for line headers
Simon Marchi via Gdb-cvs <[email protected]>
| Newsgroups | gmane.comp.gdb.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=34909f3a1dea81b0b83654c0de9375be20ac3d3b commit 34909f3a1dea81b0b83654c0de9375be20ac3d3b Author: Simon Marchi <[email protected]> Date: Sat Feb 21 15:07:34 2026 -0500 gdb/dwarf: use gdb::unordered_map for line headers Change htab_t for gdb::unordered_map, more specifically the unordered_section_and_offset_map specialization. It is no longer necessary to keep the section and offset inside the line_header structure itself, because it's just used for the map key, so remove that. I tried my best to preserve the logic in decode_line_header_for_cu, but I don't fully understand it. Change-Id: I512652e6da8b25db77ac9974135f9a06ce3d831e Approved-By: Tom Tromey <[email protected]> Diff: --- gdb/dwarf2/cu.h | 2 +- gdb/dwarf2/line-header.h | 9 ---- gdb/dwarf2/read.c | 105 +++++++++++++++-------------------------------- gdb/dwarf2/read.h | 2 +- 4 files changed, 36 insertions(+), 82 deletions(-) diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h index 182871295c8..41c1d5717cd 100644 --- a/gdb/dwarf2/cu.h +++ b/gdb/dwarf2/cu.h @@ -342,7 +342,7 @@ public: /* Header data from the line table, during full symbol processing. */ struct line_header *line_header = nullptr; /* Non-NULL if LINE_HEADER is owned by this DWARF_CU. Otherwise, - it's owned by dwarf2_per_bfd::line_header_hash. If non-NULL, + it's owned by dwarf2_per_objfile::line_headers. If non-NULL, this is the DW_TAG_compile_unit die for this CU. We'll hold on to the line header as long as this DIE is being processed. See process_die_scope. */ diff --git a/gdb/dwarf2/line-header.h b/gdb/dwarf2/line-header.h index 6c8d62d6ae2..06ce5f0e124 100644 --- a/gdb/dwarf2/line-header.h +++ b/gdb/dwarf2/line-header.h @@ -92,12 +92,6 @@ struct line_header : m_comp_dir (comp_dir) {} - /* This constructor should only be used to create line_header instances to do - hash table lookups. */ - line_header (section_and_offset sect_and_offset) - : sect_and_offset (sect_and_offset) - {} - /* Add an entry to the include directory table. */ void add_include_dir (const char *include_dir); @@ -156,9 +150,6 @@ struct line_header const std::vector<file_entry> &file_names () const { return m_file_names; } - /* Section containing this line header, and its offset into that section. */ - section_and_offset sect_and_offset; - unsigned short version {}; unsigned char minimum_instruction_length {}; unsigned char maximum_ops_per_instruction {}; diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index fbe0b0bdbec..2f27a9ac75f 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -1029,36 +1029,6 @@ dwarf2_per_objfile::relocate (unrelocated_addr addr) return gdbarch_adjust_dwarf2_addr (objfile->arch (), tem); } -/* Hash function for line_header_hash. */ - -static hashval_t -line_header_hash (const struct line_header *ofs) -{ - return section_and_offset_hash () (ofs->sect_and_offset); -} - -/* Hash function for htab_create_alloc_ex for line_header_hash. */ - -static hashval_t -line_header_hash_voidp (const void *item) -{ - const struct line_header *ofs = (const struct line_header *) item; - - return line_header_hash (ofs); -} - -/* Equality function for line_header_hash. */ - -static int -line_header_eq_voidp (const void *item_lhs, const void *item_rhs) -{ - const struct line_header *ofs_lhs = (const struct line_header *) item_lhs; - const struct line_header *ofs_rhs = (const struct line_header *) item_rhs; - - return section_and_offset_eq () (ofs_lhs->sect_and_offset, - ofs_rhs->sect_and_offset); -} - /* See declaration. */ dwarf2_per_bfd::dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names, @@ -5792,32 +5762,22 @@ decode_line_header_for_cu (struct die_info *die, struct dwarf2_cu *cu, compile_unit, then use the line header hash table if it's already created, but don't create one just yet. */ - if (per_objfile->line_header_hash == NULL + if (!per_objfile->line_headers.has_value () && die->tag == DW_TAG_partial_unit) - { - per_objfile->line_header_hash - .reset (htab_create_alloc (127, line_header_hash_voidp, - line_header_eq_voidp, - htab_delete_entry<line_header>, - xcalloc, xfree)); - } + per_objfile->line_headers.emplace (); - void **slot; - line_header line_header_local ({ get_debug_line_section (cu), line_offset }); - hashval_t line_header_local_hash = line_header_hash (&line_header_local); - if (per_objfile->line_header_hash != NULL) - { - slot = htab_find_slot_with_hash (per_objfile->line_header_hash.get (), - &line_header_local, - line_header_local_hash, NO_INSERT); + section_and_offset sao {get_debug_line_section (cu), line_offset}; - /* For DW_TAG_compile_unit we need info like symtab::linetable which - is not present in *SLOT (since if there is something in *SLOT then - it will be for a partial_unit). */ - if (die->tag == DW_TAG_partial_unit && slot != NULL) + /* For DW_TAG_compile_unit we need info like symtab::linetable which is not + present in the LINE_HEADERS hash table (since if there is something in the + hash table, it will be for a partial_unit). */ + if (die->tag == DW_TAG_partial_unit + && per_objfile->line_headers.has_value ()) + { + if (auto line_header_it = per_objfile->line_headers->find (sao); + line_header_it != per_objfile->line_headers->end ()) { - gdb_assert (*slot != NULL); - cu->line_header = (struct line_header *) *slot; + cu->line_header = line_header_it->second.get (); return; } } @@ -5832,29 +5792,32 @@ decode_line_header_for_cu (struct die_info *die, struct dwarf2_cu *cu, cu->line_header = lh.release (); cu->line_header_die_owner = die; - if (per_objfile->line_header_hash == NULL) - slot = NULL; - else - { - slot = htab_find_slot_with_hash (per_objfile->line_header_hash.get (), - &line_header_local, - line_header_local_hash, INSERT); - gdb_assert (slot != NULL); - } - if (slot != NULL && *slot == NULL) + bool inserted = false; + + if (per_objfile->line_headers.has_value ()) { - /* This newly decoded line number information unit will be owned - by line_header_hash hash table. */ - *slot = cu->line_header; - cu->line_header_die_owner = NULL; + auto [_, inserted_] + = per_objfile->line_headers->try_emplace (sao, cu->line_header); + inserted = inserted_; + + if (inserted) + { + /* There was no existing entry for this key. The new line_header + will be owned by the line_headers hash table. */ + cu->line_header_die_owner = nullptr; + } } - else + + if (!inserted) { - /* We cannot free any current entry in (*slot) as that struct line_header - may be already used by multiple CUs. Create only temporary decoded + /* There is already an existing line table with this key, or we're not + using the line_headers hash table. + + We cannot free an existing entry, as that struct line_header may + be already used by multiple CUs. Create only temporary decoded line_header for this CU - it may happen at most once for each line - number information unit. And if we're not using line_header_hash - then this is what we want as well. */ + number information unit. And if we're not using the line_headers + hash table then this is what we want as well. */ gdb_assert (die->tag != DW_TAG_partial_unit); } diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index 5dd7a0993a3..e2d75e16146 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -952,7 +952,7 @@ struct dwarf2_per_objfile die_type_hash; /* Table containing line_header indexed by (section, offset-in-section). */ - htab_up line_header_hash; + std::optional<unordered_section_and_offset_map<line_header_up>> line_headers; /* The CU containing the m_builder in scope. */ dwarf2_cu *sym_cu = nullptr;