From patchwork Fri Apr 26 17:37:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Will Hawkins X-Patchwork-Id: 89059 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 29E61384AB55 for ; Fri, 26 Apr 2024 17:38:25 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-oi1-x22d.google.com (mail-oi1-x22d.google.com [IPv6:2607:f8b0:4864:20::22d]) by sourceware.org (Postfix) with ESMTPS id 85B603858C42 for ; Fri, 26 Apr 2024 17:37:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 85B603858C42 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 85B603858C42 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::22d ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714153075; cv=none; b=rs63LVq1V0eXwdrTi1lPa9zCxkiaZgqolx3bU6LmgeuDmPNmZeWS4CDpvajoM6lHmMTiD639mTGc5uUIsSHI5GsCuibfSAvZpkfxZLE3mgEqAqyDgy+GIocZTXvrpf7C5NGbMrVEX239TUZ9KMw4NltyxgNvmFoDofPQ/GPcaGE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1714153075; c=relaxed/simple; bh=vscZ2XBzJ/9HvlOoXZ5hM5rhxbJeBY86mGnEP+koluk=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=HwiFoE4nGDQgZE1WQvUlRBdN9t8ACnfopS4LCR3p8PA6PteF9zeIXq00EQov3ZybGOm2TfL4qIQOhJLsVq14chH7Gh7yuHe3f0TeTYJizX00PVxLPhvbiadTdM/87unXKpyOO2OV1kTgBgd3rAd3K9gdaU7xRkUB3d96mRpNwRA= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-oi1-x22d.google.com with SMTP id 5614622812f47-3c70e46f3caso1547461b6e.2 for ; Fri, 26 Apr 2024 10:37:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=obs-cr.20230601.gappssmtp.com; s=20230601; t=1714153072; x=1714757872; 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=cvEMQR4L9cOBTj+uLLZ5rWgXvQp+1fuQv/pMbED7wA0=; b=zqGBkG6Z3/IAW/a3Rv1wqJcZzIXI9NQq6KZYimGyehH7DXAsfQSK9VIa3GxUDdB9P7 RaKwqoFswmsClqhaF2q/g8Go4yxoxgf8Du/oiAf3WcFwGiuMwvSVOPY4nmu2kTu9Hlmq 96s6udsR5ytM2Ot9+sCmC5NHLpRKdPAyGoHSkxRIniiFlcmXZIJSv0gZeXRSruP8m1gZ 3jyXAycwRYIAbPeeukigW98Q9s2lRpfpVIJif7uZlrT1aPUs6FW2gKLaq5FtihrGtNzl HX4Q+UOnJLH9e3MvNB2m5DyRk3KdaH6V0SkazzqcfYKueHqCojsrGjMW11cvJx8vyN9n 2cLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714153072; x=1714757872; 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=cvEMQR4L9cOBTj+uLLZ5rWgXvQp+1fuQv/pMbED7wA0=; b=aQSt5CqDg+axShj1Mmz5/H5v8eLPIUVVr5Kh+EE2XfOdJarAbEwqeb/roO0Db2rAfY n2owXwFSC6Xt5Lm56+EKtcC/qU+hvWQ0YuB95wxgrtyNxNnIpRPM1WQrdYiqcVdSMeSi OGs92eBoiYM7hldizZfh/y/ulqXSmv9ajme9nXZMN2T92sLhtYQfFutLzh1Q50r2393G pQZgUidMJPLR/e3b9zAf1n1R/oc3KT/ELjNslvYqnJlnFjGLUBv9lXB6PUwXBcgUlNUr 1kH7+uhtrbXMmhzfpP+D6LAeyRbyXcTE9lebJIvTOQreI6tcxMY2rqo5qVuBb3FXjoDk KG2w== X-Gm-Message-State: AOJu0YzXH6sbCHrM6Sy3qBbuvIhtnwCcTVnlx/PtLT/OYdDMs4z92Xfk kIobplxVYQfTuvt2sZ5H9VKQjHpV1qT/EDXN+mOWTntsbukXKXeVs6AU1zA0f5nK503o1o49AGN k X-Google-Smtp-Source: AGHT+IGPkGcS3vkbGF13uFfkihBn77lZeSKbDmKz6Ior0NNEiCQp8fx4+AC4IOL4kUtnfBpg1qahng== X-Received: by 2002:a54:4893:0:b0:3c6:eeb7:fded with SMTP id r19-20020a544893000000b003c6eeb7fdedmr3533034oic.23.1714153072362; Fri, 26 Apr 2024 10:37:52 -0700 (PDT) Received: from ininer.rhod.uc.edu ([129.137.96.15]) by smtp.gmail.com with ESMTPSA id r15-20020a0c8d0f000000b006a045780b77sm5494253qvb.51.2024.04.26.10.37.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 26 Apr 2024 10:37:51 -0700 (PDT) From: Will Hawkins To: gdb-patches@sourceware.org Cc: Will Hawkins Subject: [PATCH] gdb: Cache line headers in DWARF per CU Date: Fri, 26 Apr 2024 13:37:46 -0400 Message-ID: <20240426173749.970665-1-hawkinsw@obs.cr> X-Mailer: git-send-email 2.44.0 MIME-Version: 1.0 X-Spam-Status: No, score=-9.8 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 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 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 no longer need the scoped RAII object 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 --- gdb/dwarf2/cu.h | 6 --- gdb/dwarf2/read.c | 126 ++++++++++++++++++++++------------------------ gdb/dwarf2/read.h | 9 ++++ 3 files changed, 69 insertions(+), 72 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..c625e723256 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -6380,45 +6380,11 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu) } } -/* RAII object that represents a process_die scope: i.e., - starts/finishes processing a DIE. */ -class process_die_scope -{ -public: - process_die_scope (die_info *die, dwarf2_cu *cu) - : m_die (die), m_cu (cu) - { - /* We should only be processing DIEs not already in process. */ - gdb_assert (!m_die->in_process); - m_die->in_process = true; - } - - ~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. */ static void process_die (struct die_info *die, struct dwarf2_cu *cu) { - process_die_scope scope (die, cu); - switch (die->tag) { case DW_TAG_padding: @@ -7312,29 +7278,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 +7353,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 +7366,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 +7536,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 +7561,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. */