From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-oi1-x230.google.com (mail-oi1-x230.google.com [IPv6:2607:f8b0:4864:20::230]) by sourceware.org (Postfix) with ESMTPS id 2CB923858D35 for ; Mon, 29 Apr 2024 13:59:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2CB923858D35 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=obs.cr Authentication-Results: sourceware.org; spf=none smtp.mailfrom=obs.cr ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2CB923858D35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::230 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714399168; cv=none; b=qSzBRyOuV8ICdyzu9wDceduhJW7FS1B/U8QYw5COFP4W+mATF9gJTl25+IGVQGPVZucztYxPcorwq29kiflwJ+UaCBgJifsh/JIc8euU6oJm8EJcf3LBXGw4+w9h0358Dnu3aebWQ4ecefABjbZJ6+o94A54EydfN4/m73fsiLI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714399168; c=relaxed/simple; bh=kj8HQzAmyWeOxwzlLf/IHLQ3JuuMrpAl8lP0MaQmX1M=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=n4PsU8OARO//E2ufulcBSI9vNq2H9aKfcf2LLB0ibSovvA4Ro0T49oAG4L0TFsFV/FOjpBN40ClJ1AdTVgQMEpstUqfZDNPgQ0/zDwARfiER0xIutwo1//SqQBJY3R4iEOvA8FMf9fyeK5Jc+6VHDm34vyvHMeVVnXJXUOR20hs= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-oi1-x230.google.com with SMTP id 5614622812f47-3c5ee4ce695so1083507b6e.0 for ; Mon, 29 Apr 2024 06:59:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=obs-cr.20230601.gappssmtp.com; s=20230601; t=1714399157; x=1715003957; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=TeAIsQSGgEdZw9UNKtITooKBA8EflketNvUMu+V4o+o=; b=SVmoo2APB+cMsSbXoOkEfGumcdokyKRiQ55MRDbCSQ49c08I9vuNMuCZ/Jd0au5fXi fU6qy02j3sH6BV8UYHSirZh61Hm91F/mTSIPZUA+6iz9H4L7PcJRe34ws+IqE93X9260 T19Bo0OVrWl4m+w4s8uIHJ6p/R6ijBM+/2L9mKpnpmSxy4o2i1mEFretcFBtMZfTX+Jh ZVlijjJ8D26arWpbT1wu943xLTg4JqOG1A4s/DfH6JH2hLaj710aH8GxNfuhWc8OYOxt PSNmJonSkoEYP1aNRB8ws8P1sriHltqPgFzzJao3ytBL2QsP4AyLlNn75yaJhj2bO7uL GPhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714399157; x=1715003957; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=TeAIsQSGgEdZw9UNKtITooKBA8EflketNvUMu+V4o+o=; b=SdA5gjv8o/pQcYEciOry33EvGtPnbr4Wa+E94ODw7L33f3awNpTqjXzGYH0/jG/Nm4 bbsDEyyu7NdkGhWl6bNV3mEbM21AuAvg6SvRm3nt1d4FjzJmRMfVXR3/lzV8z/pzEN21 wNl8vH6Wohqpa/93W/ftEAuKzrh2Byb6Yt8NNgWN8Zla7ZTLYpnD3E7G13XQ+JwnfS3m otuRJMVzlKb8QVyOVVsDYkrok8mw0twM0QrF5iMdKB+ycFdCzWUUQD9X4RA9jl9ozFGb wlLSfmCFxR3f5NcFkndUONrvD72AkpSExwlk8JXxvvY+ddJvVtHIsP72pcYZ3wd5QN99 MwPA== X-Gm-Message-State: AOJu0Yw5nvMjKYXiS8xoagUkEzcRj1KH3h9eRvPiUMZ76f0+a/3ui9DZ T81+xaaWF+uxOrY8x76LDOlAQ3xUuvQDtQLbwtVWALB8FuA8N0oYOkq2tzMW29407QEKmoAgIFx o X-Google-Smtp-Source: AGHT+IFNYJN1JCkbCsMp0ZZf0xXeFa5JzMPyjm51qQmBipAZVQHyZDTMl9NKiVnhTVz3wvFvQguXTA== X-Received: by 2002:aca:1716:0:b0:3c8:64bc:f447 with SMTP id j22-20020aca1716000000b003c864bcf447mr5091110oii.40.1714399157101; Mon, 29 Apr 2024 06:59:17 -0700 (PDT) Received: from ininer.rhod.uc.edu ([129.137.96.15]) by smtp.gmail.com with ESMTPSA id u18-20020a0ca712000000b00698fd83ac04sm7723500qva.135.2024.04.29.06.59.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 29 Apr 2024 06:59:16 -0700 (PDT) From: Will Hawkins To: gdb-patches@sourceware.org Cc: Will Hawkins Subject: [PATCH v2] gdb: Cache line headers in DWARF per CU Date: Mon, 29 Apr 2024 09:59:13 -0400 Message-ID: <20240429135915.1076010-1-hawkinsw@obs.cr> X-Mailer: git-send-email 2.44.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-9.9 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: When the line headers of a DWARF unit are read, make sure that they are available for reuse by storing them in the per CU. A view of that data structure will be given to each of the dwarf2_cus as they are instantiated for reading debugging information. As a result, we can simplify the scoped RAII object (by removing code for deallocating a line header upon the completion of reading DWARF debugging information). Tested on x86_64-redhat-linux and aarch64-linux-gnu. Signed-off-by: Will Hawkins --- v1 -> v2: - Add back the in-process die RAII object to protect against infinite recursion. gdb/dwarf2/cu.h | 6 --- gdb/dwarf2/read.c | 108 +++++++++++++++++++++++++++------------------- gdb/dwarf2/read.h | 9 ++++ 3 files changed, 72 insertions(+), 51 deletions(-) diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h index 58e89960aad..c2e02a0db13 100644 --- a/gdb/dwarf2/cu.h +++ b/gdb/dwarf2/cu.h @@ -158,12 +158,6 @@ struct dwarf2_cu /* 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, - 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. */ - die_info *line_header_die_owner = nullptr; /* A list of methods which need to have physnames computed after all type information has been read. */ diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 061db8c2a2a..71d19510491 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -6385,8 +6385,8 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu) class process_die_scope { public: - process_die_scope (die_info *die, dwarf2_cu *cu) - : m_die (die), m_cu (cu) + process_die_scope (die_info *die) + : m_die (die) { /* We should only be processing DIEs not already in process. */ gdb_assert (!m_die->in_process); @@ -6396,20 +6396,10 @@ class process_die_scope ~process_die_scope () { m_die->in_process = false; - - /* If we're done processing the DIE for the CU that owns the line - header, we don't need the line header anymore. */ - if (m_cu->line_header_die_owner == m_die) - { - delete m_cu->line_header; - m_cu->line_header = NULL; - m_cu->line_header_die_owner = NULL; - } } private: die_info *m_die; - dwarf2_cu *m_cu; }; /* Process a die and its children. */ @@ -6417,7 +6407,7 @@ class process_die_scope static void process_die (struct die_info *die, struct dwarf2_cu *cu) { - process_die_scope scope (die, cu); + process_die_scope scope (die); switch (die->tag) { @@ -7312,29 +7302,38 @@ find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu) return *cu->per_cu->fnd; } -/* Handle DW_AT_stmt_list for a compilation unit. - DIE is the DW_TAG_compile_unit die for CU. - COMP_DIR is the compilation directory. LOWPC is passed to - dwarf_decode_lines. See dwarf_decode_lines comments about it. */ - static void -handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, - const file_and_directory &fnd, unrelocated_addr lowpc, - bool have_code) /* ARI: editCase function */ +ensure_line_header_read (struct dwarf2_cu *cu, struct die_info *die, + const file_and_directory &fnd, + sect_offset line_offset) { dwarf2_per_objfile *per_objfile = cu->per_objfile; - struct attribute *attr; + dwarf2_per_cu_data *per_cu = cu->per_cu; hashval_t line_header_local_hash; void **slot; - int decode_mapping; - - gdb_assert (! cu->per_cu->is_debug_types); - - attr = dwarf2_attr (die, DW_AT_stmt_list, cu); - if (attr == NULL || !attr->form_is_unsigned ()) - return; - sect_offset line_offset = (sect_offset) attr->as_unsigned (); + /* There are two places for storing/finding line headers: + 1. Per CU: When DIE is not a partial unit, the decoded + line header is owned by the per CU. In this case, the + job of this function is to simply give out a copy of + that pointer to CU -- the per cu outlives CU so this + lending is safe. + 2. Line Header Hash: When the DIE is a partial unit, the + decoded line header is owned by the line header hash. + In this case, the job of this function is to simply + give out a copy of the appropriate entry in the hash. + Caveat: If a decoded line header of a partial unit + does not fit in the line header hash, it will be + stored in/owned by the per cu. + Of course, the first time that the line header is decoded + it must be put in the proper place according to the rules + above. That is the other job of this function. */ + + if (per_cu->line_headers != NULL) + { + cu->line_header = per_cu->line_headers.get (); + return; + } /* The line header hash table is only created if needed (it exists to prevent redundant reading of the line table for partial_units). @@ -7378,9 +7377,6 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, if (lh == NULL) return; - cu->line_header = lh.release (); - cu->line_header_die_owner = die; - if (per_objfile->line_header_hash == NULL) slot = NULL; else @@ -7394,18 +7390,43 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, { /* 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; + *slot = cu->line_header = lh.release (); } else { /* We cannot free any current entry in (*slot) 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. */ + may be already used by multiple CUs. Therefore, this newly read line + header will be owned by the per_cu. */ gdb_assert (die->tag != DW_TAG_partial_unit); + + per_cu->line_headers = std::move (lh); + cu->line_header = per_cu->line_headers.get (); } +} + +/* Handle DW_AT_stmt_list for a compilation unit. + DIE is the DW_TAG_compile_unit die for CU. + COMP_DIR is the compilation directory. LOWPC is passed to + dwarf_decode_lines. See dwarf_decode_lines comments about it. */ + +static void +handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, + const file_and_directory &fnd, unrelocated_addr lowpc, + bool have_code) /* ARI: editCase function */ +{ + struct attribute *attr; + int decode_mapping; + + gdb_assert (! cu->per_cu->is_debug_types); + + attr = dwarf2_attr (die, DW_AT_stmt_list, cu); + if (attr == NULL || !attr->form_is_unsigned ()) + return; + + sect_offset line_offset = (sect_offset) attr->as_unsigned (); + + ensure_line_header_read (cu, die, fnd, line_offset); + decode_mapping = (die->tag != DW_TAG_partial_unit); /* The have_code check is here because, if LOWPC and HIGHPC are both 0x0, then there won't be any interesting code in the CU, but a check later on @@ -7539,13 +7560,13 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die) /* We have to handle the case of both a missing DW_AT_stmt_list or bad debug info. */ - line_header_up lh; if (attr != NULL && attr->form_is_unsigned ()) { + file_and_directory &fnd = find_file_and_directory (die, this); sect_offset line_offset = (sect_offset) attr->as_unsigned (); - lh = dwarf_decode_line_header (line_offset, this, nullptr); + ensure_line_header_read (this, die, fnd, line_offset); } - if (lh == NULL) + if (line_header == NULL) { if (first_time) start_compunit_symtab ("", NULL, 0); @@ -7564,9 +7585,6 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die) return; } - line_header = lh.release (); - line_header_die_owner = die; - if (first_time) { struct compunit_symtab *cust = start_compunit_symtab ("", NULL, 0); diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index 73def88c4c0..ed659fbd4ca 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -25,6 +25,7 @@ #include "dwarf2/comp-unit-head.h" #include "dwarf2/file-and-dir.h" #include "dwarf2/index-cache.h" +#include "dwarf2/line-header.h" #include "dwarf2/mapped-index.h" #include "dwarf2/section.h" #include "dwarf2/cu.h" @@ -222,6 +223,14 @@ struct dwarf2_per_cu_data have one. */ std::unique_ptr fnd; + /* The decoded line headers for this CU. This is cached so that + there is no need to refetch it repeatedly. ensure_line_headers_read + in read.c is responsible for transferring a view of this structure + to dwarf2_cus as they are instantiated. This may be nullptr when + the decoded line header is owned by the line header hash associated + with the per objfile in the presence of a partial unit. */ + std::unique_ptr line_headers; + /* The file table. This can be NULL if there was no file table or it's currently not read in. NOTE: This points into dwarf2_per_objfile->per_bfd->quick_file_names_table. */ -- 2.44.0