From patchwork Tue Mar 18 03:16:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 108277 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 68E773858290 for ; Tue, 18 Mar 2025 03:18:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 68E773858290 Authentication-Results: sourceware.org; dkim=fail reason="signature verification failed" (1024-bit key, unprotected) header.d=polymtl.ca header.i=@polymtl.ca header.a=rsa-sha256 header.s=default header.b=OXDWEzJ3 X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 3178F3858D29 for ; Tue, 18 Mar 2025 03:16:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3178F3858D29 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 3178F3858D29 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1742267800; cv=none; b=jVaOq6B9CaDtqg60C2ukPjVgYq4jy73240Xig7ungjbFtihMU4Q6lXRj4ArbYccATuLVS8TjsqaT8YmTfGb3Z7/jhCAl4RnETdluvuSxCbDPukcuv96TN8+5dwf+h9gwY9WRrApD3M8UEapp7F7MvyvSQc6mQHmzQfxEMlxCEss= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1742267800; c=relaxed/simple; bh=97kT4Jtc++VEyMd83ICLcOR3L5JYMIJyy3enx/xLWEA=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Xo0B5LtHHOeEuzE37Qc0OHImIxUO17ROSgd5Cbn7Y3wCkMktAJKOHUlk4RT3tKFwPHBvdXWS/rgZX2sicQA3f+MNTCyQ2/zO9v/yPc3XloHENFihYudVPKqlFhlcvkPvM/NlBCcPhY5T4TWTOrQMmXaOSDFzjs8xTmoRrzceTF4= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3178F3858D29 Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 52I3GYdc166922 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 17 Mar 2025 23:16:39 -0400 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 52I3GYdc166922 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1742267799; bh=Pv9cArTK5dUKR1Ol7GggQSXdgzg5JQpHSLGoAN8tY3w=; h=From:To:Cc:Subject:Date:From; b=OXDWEzJ3Ytm+EGPIzfeIc8zoNxRttQArhf3vxVgVIREtqagJUFBYDwA49Y3qcBOth 9k91YHPGqvt/Tr/f/ycWHlqg83+iGUJsguTAyfX3PVLhsZQHN1qOuxZJw1uWnF1d/4 sE0UkCHX82x1twP56K2Oydqn1Layv7A/bmFn85Pc= Received: by simark.ca (Postfix, from userid 112) id D3B2B1E114; Mon, 17 Mar 2025 23:16:34 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-Spam-Level: X-Spam-Status: No, score=-3187.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 6F0381E05C; Mon, 17 Mar 2025 23:16:32 -0400 (EDT) From: simon.marchi@polymtl.ca To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 1/2] gdb/dwarf: use gdb::unordered_map for dwarf2_per_bfd::{quick_file_names_table, type_unit_groups} Date: Mon, 17 Mar 2025 23:16:24 -0400 Message-ID: <20250318031631.917226-1-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.48.1 MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Tue, 18 Mar 2025 03:16:34 +0000 X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org From: Simon Marchi Change these two hash tables to use gdb::unordered_map. I changed these two at the same time because they both use the same key, a stmt_list_hash. Unlike other previous patches that used a gdb::unordered_set, use an unordered_map here because the key isn't found in the element itself (well, it was before, because of how htab works, but it didn't need to be). You'll notice that the type_unit_group structure is empty. That structure isn't really needed. It is removed in the following patch. Regression tested on Debian 12 amd64 with a bunch of DWARF target boards. Change-Id: Iec2289958d0f755cab8198f5b72ecab48358ba11 --- gdb/dwarf2/read-debug-names.c | 5 +- gdb/dwarf2/read-gdb-index.c | 2 - gdb/dwarf2/read.c | 189 ++++++++-------------------------- gdb/dwarf2/read.h | 21 ++-- 4 files changed, 60 insertions(+), 157 deletions(-) base-commit: a7e5d97c123b5164460a604a154a239fbcfadd86 diff --git a/gdb/dwarf2/read-debug-names.c b/gdb/dwarf2/read-debug-names.c index 8c265dd6b03f..edac713f1838 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 (per_bfd->index_table.get ())); diff --git a/gdb/dwarf2/read-gdb-index.c b/gdb/dwarf2/read-gdb-index.c index f6c73d0c98a8..343916309d7c 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 ed7558933dfa..127cedd980be 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; - /* 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 () (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 () + (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_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 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 @@ -3342,56 +3295,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, - 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 (); - - 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. */ @@ -3399,14 +3308,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? */ @@ -3428,21 +3332,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 (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 (); ++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. @@ -3548,7 +3447,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; @@ -3803,8 +3702,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 d498eeb00e06..7ebebee9791f 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; +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; + /* Some DWARF data can be shared across objfiles who share the same BFD, this data is stored in this object. @@ -605,7 +616,8 @@ struct dwarf2_per_bfd /* 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 + type_unit_groups; /* Set of signatured_types, used to look up by signature. */ signatured_type_set signatured_types; @@ -644,7 +656,8 @@ struct dwarf2_per_bfd 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 + quick_file_names_table; /* The CUs we recently read. */ std::vector just_read_cus; @@ -1195,10 +1208,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 From patchwork Tue Mar 18 03:16:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 108278 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0A6F93857C5D for ; Tue, 18 Mar 2025 03:18:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0A6F93857C5D Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=polymtl.ca header.i=@polymtl.ca header.a=rsa-sha256 header.s=default header.b=ZfmJ2ZQX X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.polymtl.ca (smtp.polymtl.ca [132.207.4.11]) by sourceware.org (Postfix) with ESMTPS id 015C03858D3C for ; Tue, 18 Mar 2025 03:16:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 015C03858D3C Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=polymtl.ca Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=polymtl.ca ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 015C03858D3C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=132.207.4.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1742267801; cv=none; b=C0oD+0+MprzUc0bwqMkBKYnEprLl/4Roe9fUvF5U0EGfuyNm44OUgHJtrW+sLcnaId9juuMl4sqIQnUboJ4C4lZR4FKEq962mCAgq7YEArHJr1/q6Q2+Ch5fCZ/HkfNHjJWBfnLYw9moqcOzLErp275I7/kQc0IIO0ib4oD9Nys= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1742267801; c=relaxed/simple; bh=CfEvu/5m8zTIDG0L/lUColdmUUsb4cUYWEXQMGsk1yA=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=w2WxjH4nSKRbYB88CrioAmt1mr5fBPtXbhEmKyILe/G1dtTyG1jSPyJd0sIamEbt0bqVKDxqwFBDYE8y1iMyXhRlaBQjO4zE+mw8juRtRElKMcUb1HSoDH4MpztwSpXOpP4AZFiX/mxPFhgnoTe+Qg4Vno/nL6qi0GpklxMxMeA= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 015C03858D3C Received: from simark.ca (simark.ca [158.69.221.121]) (authenticated bits=0) by smtp.polymtl.ca (8.14.7/8.14.7) with ESMTP id 52I3GZge166933 (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 17 Mar 2025 23:16:40 -0400 DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.polymtl.ca 52I3GZge166933 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=polymtl.ca; s=default; t=1742267800; bh=GG2ZS0rpoaux97jFAGNBi+pxIqgT0Hw4r8XMLa2hPqk=; h=From:To:Cc:Subject:Date:In-Reply-To:From; b=ZfmJ2ZQX9enYAg4VpOqIpS1atoEwvbiCiBah5TIYtJCBNDB7Og8nPAdWe3Bg2fTm2 izc5FdsS5q4FB7XR5NFSYBNzx32LEFGm/IPdymWqphP6SLXbz13Tm3Q+CYfUcissxk paq7Dq83OQ2UMCvd0DNexOuNX6wYxU5LDk3LvAWk= Received: by simark.ca (Postfix, from userid 112) id C444C1E11B; Mon, 17 Mar 2025 23:16:35 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-Spam-Level: X-Spam-Status: No, score=-3187.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 Received: from simark.localdomain (modemcable238.237-201-24.mc.videotron.ca [24.201.237.238]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id 398A81E0C3; Mon, 17 Mar 2025 23:16:33 -0400 (EDT) From: simon.marchi@polymtl.ca To: gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH 2/2] gdb/dwarf: remove type_unit_group Date: Mon, 17 Mar 2025 23:16:25 -0400 Message-ID: <20250318031631.917226-2-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250318031631.917226-1-simon.marchi@polymtl.ca> References: <20250318031631.917226-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 X-Poly-FromMTA: (simark.ca [158.69.221.121]) at Tue, 18 Mar 2025 03:16:35 +0000 X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~patchwork=sourceware.org@sourceware.org From: Simon Marchi The type_unit_group is an indirection between a stmt_list_hash (possible dwo_unit + line table section offset) and a type_unit_group_unshareable that provides no real value. In dwarf2_per_objfile, we maintain a stmt_list_hash -> type_unit_group mapping, and in dwarf2_per_objfile, we maintain a type_unit_group_unshareable mapping. The type_unit_group type is empty and only exists to have an identity and to be a link between the two mappings. This patch changes it so that we have a single stmt_list_hash -> type_unit_group_unshareable mapping. Regression tested on Debian 12 amd64 with a bunch of DWARF target boards. Change-Id: I9c5778ecb18963f353e9dd058e0f8152f7d8930c --- gdb/dwarf2/read.c | 73 +++++++++++------------------------------------ gdb/dwarf2/read.h | 52 ++++++++++++++++++--------------- 2 files changed, 46 insertions(+), 79 deletions(-) diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 127cedd980be..3ac6ad6e1f0d 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -265,29 +265,6 @@ struct loclists_rnglists_header unsigned int offset_entry_count; }; -/* A struct that can be used as a hash key for tables based on DW_AT_stmt_list. - This includes type_unit_group and quick_file_names. */ - -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; - - /* Offset in .debug_line or .debug_line.dwo. */ - sect_offset line_sect_off; -}; - -/* Each element of dwarf2_per_bfd->type_unit_groups is a pointer to - an object of this type. This contains elements of type unit groups - that can be shared across objfiles. The non-shareable parts are in - type_unit_group_unshareable. */ - -struct type_unit_group -{ -}; - /* These sections are what may appear in a (real or virtual) DWO file. */ struct dwo_sections @@ -2552,7 +2529,7 @@ fill_in_sig_entry_from_dwo_entry (dwarf2_per_objfile *per_objfile, gdb_assert (to_underlying (sig_entry->type_offset_in_section) == 0 || (to_underlying (sig_entry->type_offset_in_section) == to_underlying (dwo_entry->type_offset_in_tu))); - gdb_assert (sig_entry->type_unit_group == NULL); + gdb_assert (!sig_entry->type_unit_group_key.has_value ()); gdb_assert (sig_entry->dwo_unit == NULL || sig_entry->dwo_unit == dwo_entry); @@ -3301,14 +3278,13 @@ cutu_reader::cutu_reader (dwarf2_per_cu *this_cu, #define NO_STMT_LIST_TYPE_UNIT_PSYMTAB (1 << 31) #define NO_STMT_LIST_TYPE_UNIT_PSYMTAB_SIZE 10 -/* Look up the type_unit_group for type unit CU, and create it if necessary. - STMT_LIST is a DW_AT_stmt_list attribute. */ +/* Get the type unit group key for type unit CU. STMT_LIST is a DW_AT_stmt_list + attribute. */ -static struct type_unit_group * -get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list) +static stmt_list_hash +get_type_unit_group_key (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; unsigned int line_offset; @@ -3332,16 +3308,7 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list) ++tu_stats->nr_stmt_less_type_units; } - stmt_list_hash key {cu->dwo_unit, static_cast (line_offset)}; - auto [it, inserted] = per_bfd->type_unit_groups.emplace (key, nullptr); - - if (inserted) - { - (*it).second = std::make_unique (); - ++tu_stats->nr_symtabs; - } - - return it->second.get (); + return {cu->dwo_unit, static_cast (line_offset)}; } /* Subroutine of dwarf2_build_psymtabs_hard to simplify it. @@ -3446,9 +3413,6 @@ build_type_psymtabs (dwarf2_per_objfile *per_objfile, abbrev_table_up abbrev_table; 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.empty ()); - if (per_objfile->per_bfd->all_type_units.size () == 0) return; @@ -4775,16 +4739,15 @@ rust_union_quirks (struct dwarf2_cu *cu) /* See read.h. */ type_unit_group_unshareable * -dwarf2_per_objfile::get_type_unit_group_unshareable (type_unit_group *tu_group) +dwarf2_per_objfile::get_type_unit_group_unshareable + (stmt_list_hash tu_group_key) { - auto iter = m_type_units.find (tu_group); - if (iter != m_type_units.end ()) - return iter->second.get (); + auto [it, inserted] = m_type_units.emplace (tu_group_key, nullptr); - type_unit_group_unshareable_up uniq (new type_unit_group_unshareable); - type_unit_group_unshareable *result = uniq.get (); - m_type_units[tu_group] = std::move (uniq); - return result; + if (inserted) + it->second = std::make_unique (); + + return it->second.get (); } struct type * @@ -5056,7 +5019,7 @@ process_full_type_unit (dwarf2_cu *cu) of it with end_expandable_symtab. Otherwise, complete the addition of this TU's symbols to the existing symtab. */ type_unit_group_unshareable *tug_unshare = - per_objfile->get_type_unit_group_unshareable (sig_type->type_unit_group); + per_objfile->get_type_unit_group_unshareable (*sig_type->type_unit_group_key); if (tug_unshare->compunit_symtab == NULL) { buildsym_compunit *builder = cu->get_builder (); @@ -6247,7 +6210,6 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) void dwarf2_cu::setup_type_unit_groups (struct die_info *die) { - struct type_unit_group *tu_group; int first_time; struct attribute *attr; unsigned int i; @@ -6260,16 +6222,15 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die) /* If we're using .gdb_index (includes -readnow) then per_cu->type_unit_group may not have been set up yet. */ - if (sig_type->type_unit_group == NULL) - sig_type->type_unit_group = get_type_unit_group (this, attr); - tu_group = sig_type->type_unit_group; + if (!sig_type->type_unit_group_key.has_value ()) + sig_type->type_unit_group_key = get_type_unit_group_key (this, attr); /* If we've already processed this stmt_list there's no real need to do it again, we could fake it and just recreate the part we need (file name,index -> symtab mapping). If data shows this optimization is useful we can do it then. */ type_unit_group_unshareable *tug_unshare - = per_objfile->get_type_unit_group_unshareable (tu_group); + = per_objfile->get_type_unit_group_unshareable (*sig_type->type_unit_group_key); first_time = tug_unshare->compunit_symtab == NULL; /* We have to handle the case of both a missing DW_AT_stmt_list or bad diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index 7ebebee9791f..82a477ca8394 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -55,7 +55,6 @@ struct dwarf2_per_cu; struct mapped_index; struct mapped_debug_names; struct signatured_type; -struct type_unit_group; /* One item on the queue of compilation units to read in full symbols for. */ @@ -74,6 +73,27 @@ struct dwarf2_queue_item dwarf2_per_objfile *per_objfile; }; +/* A struct that can be used as a hash key for tables based on DW_AT_stmt_list. + This includes type_unit_group and quick_file_names. */ + +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; + + /* Offset in .debug_line or .debug_line.dwo. */ + sect_offset line_sect_off; +}; + +struct stmt_list_hash_hash +{ + using is_avalanching = void; + + std::uint64_t operator() (const stmt_list_hash &key) const noexcept; +}; + /* A deleter for dwarf2_per_cu that knows to downcast to signatured_type as appropriate. This approach lets us avoid a virtual destructor, which saves a bit of space. */ @@ -376,8 +396,9 @@ struct signatured_type : public dwarf2_per_cu sect_offset type_offset_in_section {}; /* Type units are grouped by their DW_AT_stmt_list entry so that they - can share them. This points to the containing symtab. */ - struct type_unit_group *type_unit_group = nullptr; + can share them. This is the key of the group this type unit is part + of. */ + std::optional type_unit_group_key; /* Containing DWO unit. This field is valid iff per_cu.reading_dwo_directly. */ @@ -467,17 +488,6 @@ struct dwp_file; using dwp_file_up = std::unique_ptr; -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; - /* Some DWARF data can be shared across objfiles who share the same BFD, this data is stored in this object. @@ -614,11 +624,6 @@ struct dwarf2_per_bfd std::vector all_comp_units_index_cus; std::vector all_comp_units_index_tus; - /* Table of struct type_unit_group objects. - The hash key is the DW_AT_stmt_list value. */ - gdb::unordered_map - type_unit_groups; - /* Set of signatured_types, used to look up by signature. */ signatured_type_set signatured_types; @@ -828,10 +833,10 @@ struct dwarf2_per_objfile /* Set the compunit_symtab associated to PER_CU. */ void set_symtab (const dwarf2_per_cu *per_cu, compunit_symtab *symtab); - /* Get the type_unit_group_unshareable corresponding to TU_GROUP. If one + /* Get the type_unit_group_unshareable corresponding to TU_GROUP_KEY. If one does not exist, create it. */ type_unit_group_unshareable *get_type_unit_group_unshareable - (type_unit_group *tu_group); + (stmt_list_hash tu_group_key); struct type *get_type_for_signatured_type (signatured_type *sig_type) const; @@ -898,9 +903,10 @@ struct dwarf2_per_objfile expanded yet. */ std::vector m_symtabs; - /* Map from a type unit group to the corresponding unshared + /* Map from a type unit group key to the corresponding unshared structure. */ - gdb::unordered_map + gdb::unordered_map m_type_units; /* Map from signatured types to the corresponding struct type. */