From patchwork Sat Jan 6 00:26:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 25243 Received: (qmail 5476 invoked by alias); 6 Jan 2018 00:26:30 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 5297 invoked by uid 89); 6 Jan 2018 00:26:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=sk:discard, destruction, 95407, held X-HELO: gateway33.websitewelcome.com Received: from gateway33.websitewelcome.com (HELO gateway33.websitewelcome.com) (192.185.146.68) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 06 Jan 2018 00:26:26 +0000 Received: from cm12.websitewelcome.com (cm12.websitewelcome.com [100.42.49.8]) by gateway33.websitewelcome.com (Postfix) with ESMTP id 5BA0FEB0FA9 for ; Fri, 5 Jan 2018 18:26:24 -0600 (CST) Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with SMTP id XcJce3roZzzFjXcJcemzJV; Fri, 05 Jan 2018 18:26:24 -0600 Received: from 71-218-90-63.hlrn.qwest.net ([71.218.90.63]:39986 helo=pokyo.Home) by box5379.bluehost.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.89) (envelope-from ) id 1eXcJc-0035k1-4l; Fri, 05 Jan 2018 18:26:24 -0600 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [RFA 2/6] Allocate abbrev_table with new Date: Fri, 5 Jan 2018 17:26:17 -0700 Message-Id: <20180106002621.21099-3-tom@tromey.com> In-Reply-To: <20180106002621.21099-1-tom@tromey.com> References: <20180106002621.21099-1-tom@tromey.com> X-BWhitelist: no X-Source-L: No X-Exim-ID: 1eXcJc-0035k1-4l X-Source-Sender: 71-218-90-63.hlrn.qwest.net (pokyo.Home) [71.218.90.63]:39986 X-Source-Auth: tom+tromey.com X-Email-Count: 3 X-Source-Cap: ZWx5bnJvYmk7ZWx5bnJvYmk7Ym94NTM3OS5ibHVlaG9zdC5jb20= X-Local-Domain: yes This changes dwarf2read.c to allocate abbrev tables using "new", and then updates the users. This is somewhat complicated because ownership rules for abbrev tables are obscure and involve a more than usual amount of cleanup manipulation. 2018-01-05 Tom Tromey * dwarf2read.c (class auto_free_abbrev_table): New. (struct abbrev_table): Add constructor, destructor. : Declare methods. (read_cutu_die_from_dwo): Add abbrev_table parameter. (init_cutu_and_read_dies): Update. (init_cutu_and_read_dies_no_follow): Use auto_free_abbrev_table. (build_type_psymtabs_1, peek_die_abbrev, read_full_die_1): Update. (abbrev_table::alloc_abbrev): Rename from abbrev_table_alloc_abbrev. (abbrev_table::add_abbrev): Rename from abbrev_table_add_abbrev. (abbrev_table::lookup_abbrev): Rename from abbrev_table_lookup_abbrev. (abbrev_table_read_table): Return a unique_ptr. (abbrev_table_free, abbrev_table_free_cleanup): Remove. (dwarf2_read_abbrevs): Update. (dwarf2_free_abbrev_table): Change argument type to dwarf2_cu*. --- gdb/ChangeLog | 20 ++++++ gdb/dwarf2read.c | 190 +++++++++++++++++++++++++++---------------------------- 2 files changed, 112 insertions(+), 98 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5ad43d963a..339a4e728a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,25 @@ 2018-01-05 Tom Tromey + * dwarf2read.c (class auto_free_abbrev_table): New. + (struct abbrev_table): Add constructor, destructor. + : Declare methods. + (read_cutu_die_from_dwo): Add abbrev_table parameter. + (init_cutu_and_read_dies): Update. + (init_cutu_and_read_dies_no_follow): Use auto_free_abbrev_table. + (build_type_psymtabs_1, peek_die_abbrev, read_full_die_1): + Update. + (abbrev_table::alloc_abbrev): Rename from + abbrev_table_alloc_abbrev. + (abbrev_table::add_abbrev): Rename from abbrev_table_add_abbrev. + (abbrev_table::lookup_abbrev): Rename from + abbrev_table_lookup_abbrev. + (abbrev_table_read_table): Return a unique_ptr. + (abbrev_table_free, abbrev_table_free_cleanup): Remove. + (dwarf2_read_abbrevs): Update. + (dwarf2_free_abbrev_table): Change argument type to dwarf2_cu*. + +2018-01-05 Tom Tromey + * dwarf2read.c (dwarf2_compute_name): Update comment. (read_func_scope, read_variable): Update. (new_symbol): Remove. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 92c4903241..7fd68c54fa 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -774,6 +774,28 @@ struct dwarf2_cu unsigned int processing_has_namespace_info : 1; }; +static void dwarf2_free_abbrev_table (struct dwarf2_cu *); + +/* Free an abbrev table on destruction. */ + +class auto_free_abbrev_table +{ +public: + auto_free_abbrev_table (struct dwarf2_cu *cu) + : m_cu (cu) + { + } + + ~auto_free_abbrev_table () + { + dwarf2_free_abbrev_table (m_cu); + } + +private: + + struct dwarf2_cu *m_cu; +}; + /* Persistent data held for a compilation unit, even when not processing it. We put a pointer to this structure in the read_symtab_private field of the psymtab. */ @@ -1497,12 +1519,35 @@ struct attr_abbrev struct abbrev_table { + abbrev_table (sect_offset off) + : sect_off (off) + { + abbrevs = + XOBNEWVEC (&abbrev_obstack, struct abbrev_info *, ABBREV_HASH_SIZE); + memset (abbrevs, 0, ABBREV_HASH_SIZE * sizeof (struct abbrev_info *)); + } + + DISABLE_COPY_AND_ASSIGN (abbrev_table); + + /* Allocate space for a struct abbrev_info object in + ABBREV_TABLE. */ + struct abbrev_info *alloc_abbrev (); + + /* Add an abbreviation to the table. */ + void add_abbrev (unsigned int abbrev_number, struct abbrev_info *abbrev); + + /* Look up an abbrev in the table. + Returns NULL if the abbrev is not found. */ + + struct abbrev_info *lookup_abbrev (unsigned int abbrev_number); + + /* Where the abbrev table came from. This is used as a sanity check when the table is used. */ sect_offset sect_off; /* Storage for the abbrev table. */ - struct obstack abbrev_obstack; + auto_obstack abbrev_obstack; /* Hash table of abbrevs. This is an array of size ABBREV_HASH_SIZE allocated in abbrev_obstack. @@ -1739,21 +1784,12 @@ static void dwarf2_read_symtab (struct partial_symtab *, static void psymtab_to_symtab_1 (struct partial_symtab *); -static struct abbrev_info *abbrev_table_lookup_abbrev - (const struct abbrev_table *, unsigned int); - -static struct abbrev_table *abbrev_table_read_table +static std::unique_ptr abbrev_table_read_table (struct dwarf2_section_info *, sect_offset); -static void abbrev_table_free (struct abbrev_table *); - -static void abbrev_table_free_cleanup (void *); - static void dwarf2_read_abbrevs (struct dwarf2_cu *, struct dwarf2_section_info *); -static void dwarf2_free_abbrev_table (void *); - static unsigned int peek_abbrev_code (bfd *, const gdb_byte *); static struct partial_die_info *load_partial_dies @@ -7368,6 +7404,7 @@ init_cu_die_reader (struct die_reader_specs *reader, are filled in with the info of the DIE from the DWO file. ABBREV_TABLE_PROVIDED is non-zero if the caller of init_cutu_and_read_dies provided an abbrev table to use. + *ABBREV_TABLE may be filled in with a new abbrev table. The result is non-zero if a valid (non-dummy) DIE was found. */ static int @@ -7379,7 +7416,8 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu, struct die_reader_specs *result_reader, const gdb_byte **result_info_ptr, struct die_info **result_comp_unit_die, - int *result_has_children) + int *result_has_children, + gdb::optional *abbrev_table) { struct objfile *objfile = dwarf2_per_objfile->objfile; struct dwarf2_cu *cu = this_cu->cu; @@ -7501,7 +7539,7 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu, init_cutu_and_read_dies owns it. */ dwarf2_read_abbrevs (cu, dwo_abbrev_section); /* Ensure the DWO abbrev table gets freed. */ - make_cleanup (dwarf2_free_abbrev_table, cu); + abbrev_table->emplace (cu); } else { @@ -7661,12 +7699,14 @@ init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu, abbrev table. When reading DWOs with skeletonless TUs, all the TUs could share abbrev tables. */ + gdb::optional abbrev_table; if (read_cutu_die_from_dwo (this_cu, sig_type->dwo_unit, 0 /* abbrev_table_provided */, NULL /* stub_comp_unit_die */, sig_type->dwo_unit->dwo_file->comp_dir, &reader, &info_ptr, - &comp_unit_die, &has_children) == 0) + &comp_unit_die, &has_children, + &abbrev_table) == 0) { /* Dummy die. */ do_cleanups (cleanups); @@ -7688,10 +7728,6 @@ init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu, caller clean it up when finished with it. */ discard_cleanups (free_cu_cleanup); - /* We can only discard free_cu_cleanup and all subsequent cleanups. - So we have to manually free the abbrev table. */ - dwarf2_free_abbrev_table (cu); - /* Link this CU into read_in_chain. */ this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain; dwarf2_per_objfile->read_in_chain = this_cu; @@ -7852,6 +7888,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, done. Note that it's important that if the CU had an abbrev table on entry we don't free it when we're done: Somewhere up the call stack it may be in use. */ + gdb::optional abbrev_table_freer; if (abbrev_table != NULL) { gdb_assert (cu->abbrev_table == NULL); @@ -7861,7 +7898,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, else if (cu->abbrev_table == NULL) { dwarf2_read_abbrevs (cu, abbrev_section); - make_cleanup (dwarf2_free_abbrev_table, cu); + abbrev_table_freer.emplace (cu); } else if (rereading_dwo_cu) { @@ -7878,6 +7915,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, Note that if USE_EXISTING_OK != 0, and THIS_CU->cu already contains a DWO CU, that this test will fail (the attribute will not be present). */ attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_name, cu); + gdb::optional abbrev_table_freer_2; if (attr) { struct dwo_unit *dwo_unit; @@ -7897,7 +7935,8 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, abbrev_table != NULL, comp_unit_die, NULL, &reader, &info_ptr, - &dwo_comp_unit_die, &has_children) == 0) + &dwo_comp_unit_die, &has_children, + &abbrev_table_freer_2) == 0) { /* Dummy die. */ do_cleanups (cleanups); @@ -7927,10 +7966,6 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, caller clean it up when finished with it. */ discard_cleanups (free_cu_cleanup); - /* We can only discard free_cu_cleanup and all subsequent cleanups. - So we have to manually free the abbrev table. */ - dwarf2_free_abbrev_table (cu); - /* Link this CU into read_in_chain. */ this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain; dwarf2_per_objfile->read_in_chain = this_cu; @@ -8011,7 +8046,7 @@ init_cutu_and_read_dies_no_follow (struct dwarf2_per_cu_data *this_cu, } dwarf2_read_abbrevs (&cu, abbrev_section); - make_cleanup (dwarf2_free_abbrev_table, &cu); + auto_free_abbrev_table abbrev_table_freer (&cu); init_cu_die_reader (&reader, &cu, section, dwo_file); info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children); @@ -8483,7 +8518,7 @@ build_type_psymtabs_1 (void) { struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats; struct cleanup *cleanups; - struct abbrev_table *abbrev_table; + std::unique_ptr abbrev_table; sect_offset abbrev_offset; struct tu_abbrev_offset *sorted_by_abbrev; int i; @@ -8534,8 +8569,6 @@ build_type_psymtabs_1 (void) sizeof (struct tu_abbrev_offset), sort_tu_by_abbrev_offset); abbrev_offset = (sect_offset) ~(unsigned) 0; - abbrev_table = NULL; - make_cleanup (abbrev_table_free_cleanup, &abbrev_table); for (i = 0; i < dwarf2_per_objfile->n_type_units; ++i) { @@ -8545,13 +8578,6 @@ build_type_psymtabs_1 (void) if (abbrev_table == NULL || tu->abbrev_offset != abbrev_offset) { - if (abbrev_table != NULL) - { - abbrev_table_free (abbrev_table); - /* Reset to NULL in case abbrev_table_read_table throws - an error: abbrev_table_free_cleanup will get called. */ - abbrev_table = NULL; - } abbrev_offset = tu->abbrev_offset; abbrev_table = abbrev_table_read_table (&dwarf2_per_objfile->abbrev, @@ -8559,8 +8585,8 @@ build_type_psymtabs_1 (void) ++tu_stats->nr_uniq_abbrev_tables; } - init_cutu_and_read_dies (&tu->sig_type->per_cu, abbrev_table, 0, 0, - build_type_psymtabs_reader, NULL); + init_cutu_and_read_dies (&tu->sig_type->per_cu, abbrev_table.get (), + 0, 0, build_type_psymtabs_reader, NULL); } do_cleanups (cleanups); @@ -9514,7 +9540,7 @@ peek_die_abbrev (const gdb_byte *info_ptr, unsigned int *bytes_read, if (abbrev_number == 0) return NULL; - abbrev = abbrev_table_lookup_abbrev (cu->abbrev_table, abbrev_number); + abbrev = cu->abbrev_table->lookup_abbrev (abbrev_number); if (!abbrev) { error (_("Dwarf Error: Could not find abbrev number %d in %s" @@ -17851,7 +17877,7 @@ read_full_die_1 (const struct die_reader_specs *reader, return info_ptr; } - abbrev = abbrev_table_lookup_abbrev (cu->abbrev_table, abbrev_number); + abbrev = cu->abbrev_table->lookup_abbrev (abbrev_number); if (!abbrev) error (_("Dwarf Error: could not find abbrev number %d [in module %s]"), abbrev_number, @@ -17912,12 +17938,12 @@ read_full_die (const struct die_reader_specs *reader, /* Allocate space for a struct abbrev_info object in ABBREV_TABLE. */ -static struct abbrev_info * -abbrev_table_alloc_abbrev (struct abbrev_table *abbrev_table) +struct abbrev_info * +abbrev_table::alloc_abbrev () { struct abbrev_info *abbrev; - abbrev = XOBNEW (&abbrev_table->abbrev_obstack, struct abbrev_info); + abbrev = XOBNEW (&abbrev_obstack, struct abbrev_info); memset (abbrev, 0, sizeof (struct abbrev_info)); return abbrev; @@ -17925,30 +17951,28 @@ abbrev_table_alloc_abbrev (struct abbrev_table *abbrev_table) /* Add an abbreviation to the table. */ -static void -abbrev_table_add_abbrev (struct abbrev_table *abbrev_table, - unsigned int abbrev_number, - struct abbrev_info *abbrev) +void +abbrev_table::add_abbrev (unsigned int abbrev_number, + struct abbrev_info *abbrev) { unsigned int hash_number; hash_number = abbrev_number % ABBREV_HASH_SIZE; - abbrev->next = abbrev_table->abbrevs[hash_number]; - abbrev_table->abbrevs[hash_number] = abbrev; + abbrev->next = abbrevs[hash_number]; + abbrevs[hash_number] = abbrev; } /* Look up an abbrev in the table. Returns NULL if the abbrev is not found. */ -static struct abbrev_info * -abbrev_table_lookup_abbrev (const struct abbrev_table *abbrev_table, - unsigned int abbrev_number) +struct abbrev_info * +abbrev_table::lookup_abbrev (unsigned int abbrev_number) { unsigned int hash_number; struct abbrev_info *abbrev; hash_number = abbrev_number % ABBREV_HASH_SIZE; - abbrev = abbrev_table->abbrevs[hash_number]; + abbrev = abbrevs[hash_number]; while (abbrev) { @@ -17961,13 +17985,12 @@ abbrev_table_lookup_abbrev (const struct abbrev_table *abbrev_table, /* Read in an abbrev table. */ -static struct abbrev_table * +static std::unique_ptr abbrev_table_read_table (struct dwarf2_section_info *section, sect_offset sect_off) { struct objfile *objfile = dwarf2_per_objfile->objfile; bfd *abfd = get_section_bfd_owner (section); - struct abbrev_table *abbrev_table; const gdb_byte *abbrev_ptr; struct abbrev_info *cur_abbrev; unsigned int abbrev_number, bytes_read, abbrev_name; @@ -17975,14 +17998,8 @@ abbrev_table_read_table (struct dwarf2_section_info *section, struct attr_abbrev *cur_attrs; unsigned int allocated_attrs; - abbrev_table = XNEW (struct abbrev_table); - abbrev_table->sect_off = sect_off; - obstack_init (&abbrev_table->abbrev_obstack); - abbrev_table->abbrevs = - XOBNEWVEC (&abbrev_table->abbrev_obstack, struct abbrev_info *, - ABBREV_HASH_SIZE); - memset (abbrev_table->abbrevs, 0, - ABBREV_HASH_SIZE * sizeof (struct abbrev_info *)); + std::unique_ptr abbrev_table + (new struct abbrev_table (sect_off)); dwarf2_read_section (objfile, section); abbrev_ptr = section->buffer + to_underlying (sect_off); @@ -17995,7 +18012,7 @@ abbrev_table_read_table (struct dwarf2_section_info *section, /* Loop until we reach an abbrev number of 0. */ while (abbrev_number) { - cur_abbrev = abbrev_table_alloc_abbrev (abbrev_table); + cur_abbrev = abbrev_table->alloc_abbrev (); /* read in abbrev header */ cur_abbrev->number = abbrev_number; @@ -18050,7 +18067,7 @@ abbrev_table_read_table (struct dwarf2_section_info *section, memcpy (cur_abbrev->attrs, cur_attrs, cur_abbrev->num_attrs * sizeof (struct attr_abbrev)); - abbrev_table_add_abbrev (abbrev_table, abbrev_number, cur_abbrev); + abbrev_table->add_abbrev (abbrev_number, cur_abbrev); /* Get next abbreviation. Under Irix6 the abbreviations for a compilation unit are not @@ -18063,7 +18080,7 @@ abbrev_table_read_table (struct dwarf2_section_info *section, break; abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read); abbrev_ptr += bytes_read; - if (abbrev_table_lookup_abbrev (abbrev_table, abbrev_number) != NULL) + if (abbrev_table->lookup_abbrev (abbrev_number) != NULL) break; } @@ -18071,52 +18088,29 @@ abbrev_table_read_table (struct dwarf2_section_info *section, return abbrev_table; } -/* Free the resources held by ABBREV_TABLE. */ - -static void -abbrev_table_free (struct abbrev_table *abbrev_table) -{ - obstack_free (&abbrev_table->abbrev_obstack, NULL); - xfree (abbrev_table); -} - -/* Same as abbrev_table_free but as a cleanup. - We pass in a pointer to the pointer to the table so that we can - set the pointer to NULL when we're done. It also simplifies - build_type_psymtabs_1. */ - -static void -abbrev_table_free_cleanup (void *table_ptr) -{ - struct abbrev_table **abbrev_table_ptr = (struct abbrev_table **) table_ptr; - - if (*abbrev_table_ptr != NULL) - abbrev_table_free (*abbrev_table_ptr); - *abbrev_table_ptr = NULL; -} - /* Read the abbrev table for CU from ABBREV_SECTION. */ static void dwarf2_read_abbrevs (struct dwarf2_cu *cu, struct dwarf2_section_info *abbrev_section) { - cu->abbrev_table = - abbrev_table_read_table (abbrev_section, cu->header.abbrev_sect_off); + cu->abbrev_table + = (abbrev_table_read_table (abbrev_section, cu->header.abbrev_sect_off) + .release ()); } /* Release the memory used by the abbrev table for a compilation unit. */ static void -dwarf2_free_abbrev_table (void *ptr_to_cu) +dwarf2_free_abbrev_table (struct dwarf2_cu *cu) { - struct dwarf2_cu *cu = (struct dwarf2_cu *) ptr_to_cu; - if (cu->abbrev_table != NULL) - abbrev_table_free (cu->abbrev_table); - /* Set this to NULL so that we SEGV if we try to read it later, - and also because free_comp_unit verifies this is NULL. */ - cu->abbrev_table = NULL; + { + delete cu->abbrev_table; + /* Set this to NULL so that we SEGV if we try to read it later, + and also because free_comp_unit verifies this is NULL. */ + cu->abbrev_table = NULL; + } } /* Returns nonzero if TAG represents a type that we might generate a partial