From patchwork Thu Mar 7 17:41:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 31771 Received: (qmail 33483 invoked by alias); 7 Mar 2019 17:42:09 -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 33437 invoked by uid 89); 7 Mar 2019 17:42:07 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.2 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.1 spammy=Almost X-HELO: gateway20.websitewelcome.com Received: from gateway20.websitewelcome.com (HELO gateway20.websitewelcome.com) (192.185.59.4) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 07 Mar 2019 17:42:02 +0000 Received: from cm13.websitewelcome.com (cm13.websitewelcome.com [100.42.49.6]) by gateway20.websitewelcome.com (Postfix) with ESMTP id 1B0BF400E2823 for ; Thu, 7 Mar 2019 11:42:00 -0600 (CST) Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with SMTP id 1x1rh8MaVYTGM1x1shNiRu; Thu, 07 Mar 2019 11:42:00 -0600 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=Content-Type:MIME-Version:Message-ID:In-Reply-To:Date: References:Subject:Cc:To:From:Sender:Reply-To:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=QpuBZMiietNYYdXmcyj8pRAnAIMplk8WaycEP3y9H0Y=; b=LomZXqyfyuHLycpMoYMCleyGzW 9TIRMx4ek+q3nPQcf3xmES2gCMNZRKVi80f0l51p/Bw1OvMVun8ynqnNU+VIm856fIzn7XiB42L0R P6glHm9MithIsaPEebp/jMZcD; Received: from 75-166-85-218.hlrn.qwest.net ([75.166.85.218]:60500 helo=bapiya) by box5379.bluehost.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.91) (envelope-from ) id 1h1x1r-001n34-Kk; Thu, 07 Mar 2019 11:41:59 -0600 From: Tom Tromey To: Pedro Alves Cc: Tom Tromey , gdb-patches@sourceware.org Subject: Re: [PATCH v2 22/22] Introduce and use bcache_up References: <20190227201849.32210-1-tom@tromey.com> <20190227201849.32210-23-tom@tromey.com> <6b7f0a4c-f06b-9046-c91d-ae402eae6c51@redhat.com> <87sgvyeicd.fsf@tromey.com> <84420de3-2ac8-84a5-3361-cd5baf57209f@redhat.com> Date: Thu, 07 Mar 2019 10:41:58 -0700 In-Reply-To: <84420de3-2ac8-84a5-3361-cd5baf57209f@redhat.com> (Pedro Alves's message of "Thu, 7 Mar 2019 17:09:24 +0000") Message-ID: <87o96meg49.fsf@tromey.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1.91 (gnu/linux) MIME-Version: 1.0 >>>>> "Pedro" == Pedro Alves writes: Pedro> Almost perfect. On a quick skim, the only thing missing is Pedro> renaming the now-private fields of struct bcache to have Pedro> an "m_" prefix. I think it's worth doing here since it'll Pedro> end up touching many of the same same lines you're already Pedro> touching in bcache.c. LGTM with that change. Thanks. Here is what I am checking in. Tom commit a99eb1e73b1b66143d670322ebeb639c82468aed Author: Tom Tromey Date: Thu Mar 7 04:20:19 2019 -0700 C++-ify bcache This somewhat C++-ifies bcache. It replaces bcache_xmalloc and bcache_xfree with constructors; changes some functions into methods; and changes various structures to include a bcache directly (as opposed to a pointer to a bcache). Tested by the buildbot. gdb/ChangeLog 2019-03-07 Tom Tromey * symmisc.c (print_symbol_bcache_statistics): Update. (print_objfile_statistics): Update. * symfile.c (allocate_symtab): Update. * stabsread.c: Don't include bcache.h. * psymtab.h (struct psymbol_bcache): Don't declare. (class psymtab_storage) : Now a bcache. (psymbol_bcache_init, psymbol_bcache_free) (psymbol_bcache_get_bcache): Don't declare. * psymtab.c (struct psymbol_bcache): Remove. (psymtab_storage::psymtab_storage): Update. (psymtab_storage::~psymtab_storage): Update. (psymbol_bcache_init, psymbol_bcache_free) (psymbol_bcache_get_bcache, psymbol_bcache_full): Remove. (add_psymbol_to_bcache): Update. (allocate_psymtab): Update. * objfiles.h (struct objfile_per_bfd_storage) : No longer pointers. * objfiles.c (get_objfile_bfd_data): Don't call bcache_xmalloc. (free_objfile_per_bfd_storage): Don't call bcache_xfree. * macrotab.c (macro_bcache): Update. * macroexp.c: Don't include bcache.h. * gdbtypes.c (check_types_worklist): Update. (types_deeply_equal): Remove TRY/CATCH. Update. * elfread.c (elf_symtab_read): Update. * dwarf2read.c: Don't include bcache.h. * buildsym.c (buildsym_compunit::get_macro_table): Update. * bcache.h (bcache, bcache_full, bcache_xffree, bcache_xmalloc) (print_bcache_statistics, bcache_memory_used): Don't declare. (struct bcache): Move from bcache.c. Add constructor, destructor, methods. Rename all data members. * bcache.c (struct bcache): Move to bcache.h. (bcache::expand_hash_table): Rename from expand_hash_table. (bcache): Remove. (bcache::insert): Rename from bcache_full. (bcache::compare): Rename from bcache_compare. (bcache_xmalloc): Remove. (bcache::~bcache): Rename from bcache_xfree. (bcache::print_statistics): Rename from print_bcache_statistics. (bcache::memory_used): Rename from bcache_memory_used. diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d3d6e5b4ee6..331bc740c6f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,45 @@ +2019-03-07 Tom Tromey + + * symmisc.c (print_symbol_bcache_statistics): Update. + (print_objfile_statistics): Update. + * symfile.c (allocate_symtab): Update. + * stabsread.c: Don't include bcache.h. + * psymtab.h (struct psymbol_bcache): Don't declare. + (class psymtab_storage) : Now a bcache. + (psymbol_bcache_init, psymbol_bcache_free) + (psymbol_bcache_get_bcache): Don't declare. + * psymtab.c (struct psymbol_bcache): Remove. + (psymtab_storage::psymtab_storage): Update. + (psymtab_storage::~psymtab_storage): Update. + (psymbol_bcache_init, psymbol_bcache_free) + (psymbol_bcache_get_bcache, psymbol_bcache_full): Remove. + (add_psymbol_to_bcache): Update. + (allocate_psymtab): Update. + * objfiles.h (struct objfile_per_bfd_storage) : No longer pointers. + * objfiles.c (get_objfile_bfd_data): Don't call bcache_xmalloc. + (free_objfile_per_bfd_storage): Don't call bcache_xfree. + * macrotab.c (macro_bcache): Update. + * macroexp.c: Don't include bcache.h. + * gdbtypes.c (check_types_worklist): Update. + (types_deeply_equal): Remove TRY/CATCH. Update. + * elfread.c (elf_symtab_read): Update. + * dwarf2read.c: Don't include bcache.h. + * buildsym.c (buildsym_compunit::get_macro_table): Update. + * bcache.h (bcache, bcache_full, bcache_xffree, bcache_xmalloc) + (print_bcache_statistics, bcache_memory_used): Don't declare. + (struct bcache): Move from bcache.c. Add constructor, destructor, + methods. Rename all data members. + * bcache.c (struct bcache): Move to bcache.h. + (bcache::expand_hash_table): Rename from expand_hash_table. + (bcache): Remove. + (bcache::insert): Rename from bcache_full. + (bcache::compare): Rename from bcache_compare. + (bcache_xmalloc): Remove. + (bcache::~bcache): Rename from bcache_xfree. + (bcache::print_statistics): Rename from print_bcache_statistics. + (bcache::memory_used): Rename from bcache_memory_used. + 2019-03-07 Andrew Burgess * f-lang.c (value_from_host_double): Moved to... diff --git a/gdb/bcache.c b/gdb/bcache.c index 1430953ac62..14a78474962 100644 --- a/gdb/bcache.c +++ b/gdb/bcache.c @@ -49,48 +49,6 @@ struct bstring d; }; - -/* The structure for a bcache itself. The bcache is initialized, in - bcache_xmalloc(), by filling it with zeros and then setting the - corresponding obstack's malloc() and free() methods. */ - -struct bcache -{ - /* All the bstrings are allocated here. */ - struct obstack cache; - - /* How many hash buckets we're using. */ - unsigned int num_buckets; - - /* Hash buckets. This table is allocated using malloc, so when we - grow the table we can return the old table to the system. */ - struct bstring **bucket; - - /* Statistics. */ - unsigned long unique_count; /* number of unique strings */ - long total_count; /* total number of strings cached, including dups */ - long unique_size; /* size of unique strings, in bytes */ - long total_size; /* total number of bytes cached, including dups */ - long structure_size; /* total size of bcache, including infrastructure */ - /* Number of times that the hash table is expanded and hence - re-built, and the corresponding number of times that a string is - [re]hashed as part of entering it into the expanded table. The - total number of hashes can be computed by adding TOTAL_COUNT to - expand_hash_count. */ - unsigned long expand_count; - unsigned long expand_hash_count; - /* Number of times that the half-hash compare hit (compare the upper - 16 bits of hash values) hit, but the corresponding combined - length/data compare missed. */ - unsigned long half_hash_miss_count; - - /* Hash function to be used for this bcache object. */ - unsigned long (*hash_function)(const void *addr, int length); - - /* Compare function to be used for this bcache object. */ - int (*compare_function)(const void *, const void *, int length); -}; - /* The old hash function was stolen from SDBM. This is what DB 3.0 uses now, and is better than the old one. */ @@ -123,8 +81,8 @@ hash_continue (const void *addr, int length, unsigned long h) resize our hash table. */ #define CHAIN_LENGTH_THRESHOLD (5) -static void -expand_hash_table (struct bcache *bcache) +void +bcache::expand_hash_table () { /* A table of good hash table sizes. Whenever we grow, we pick the next larger size from this table. sizes[i] is close to 1 << (i+10), @@ -143,13 +101,13 @@ expand_hash_table (struct bcache *bcache) /* Count the stats. Every unique item needs to be re-hashed and re-entered. */ - bcache->expand_count++; - bcache->expand_hash_count += bcache->unique_count; + m_expand_count++; + m_expand_hash_count += m_unique_count; /* Find the next size. */ - new_num_buckets = bcache->num_buckets * 2; + new_num_buckets = m_num_buckets * 2; for (i = 0; i < (sizeof (sizes) / sizeof (sizes[0])); i++) - if (sizes[i] > bcache->num_buckets) + if (sizes[i] > m_num_buckets) { new_num_buckets = sizes[i]; break; @@ -162,23 +120,21 @@ expand_hash_table (struct bcache *bcache) new_buckets = (struct bstring **) xmalloc (new_size); memset (new_buckets, 0, new_size); - bcache->structure_size -= (bcache->num_buckets - * sizeof (bcache->bucket[0])); - bcache->structure_size += new_size; + m_structure_size -= m_num_buckets * sizeof (m_bucket[0]); + m_structure_size += new_size; } /* Rehash all existing strings. */ - for (i = 0; i < bcache->num_buckets; i++) + for (i = 0; i < m_num_buckets; i++) { struct bstring *s, *next; - for (s = bcache->bucket[i]; s; s = next) + for (s = m_bucket[i]; s; s = next) { struct bstring **new_bucket; next = s->next; - new_bucket = &new_buckets[(bcache->hash_function (&s->d.data, - s->length) + new_bucket = &new_buckets[(m_hash_function (&s->d.data, s->length) % new_num_buckets)]; s->next = *new_bucket; *new_bucket = s; @@ -186,10 +142,9 @@ expand_hash_table (struct bcache *bcache) } /* Plug in the new table. */ - if (bcache->bucket) - xfree (bcache->bucket); - bcache->bucket = new_buckets; - bcache->num_buckets = new_num_buckets; + xfree (m_bucket); + m_bucket = new_buckets; + m_num_buckets = new_num_buckets; } @@ -199,15 +154,6 @@ expand_hash_table (struct bcache *bcache) is N bytes long. */ #define BSTRING_SIZE(n) (offsetof (struct bstring, d.data) + (n)) -/* Find a copy of the LENGTH bytes at ADDR in BCACHE. If BCACHE has - never seen those bytes before, add a copy of them to BCACHE. In - either case, return a pointer to BCACHE's copy of that string. */ -const void * -bcache (const void *addr, int length, struct bcache *cache) -{ - return bcache_full (addr, length, cache, NULL); -} - /* Find a copy of the LENGTH bytes at ADDR in BCACHE. If BCACHE has never seen those bytes before, add a copy of them to BCACHE. In either case, return a pointer to BCACHE's copy of that string. If @@ -215,7 +161,7 @@ bcache (const void *addr, int length, struct bcache *cache) returning an old entry. */ const void * -bcache_full (const void *addr, int length, struct bcache *bcache, int *added) +bcache::insert (const void *addr, int length, int *added) { unsigned long full_hash; unsigned short half_hash; @@ -227,56 +173,56 @@ bcache_full (const void *addr, int length, struct bcache *bcache, int *added) /* Lazily initialize the obstack. This can save quite a bit of memory in some cases. */ - if (bcache->total_count == 0) + if (m_total_count == 0) { /* We could use obstack_specify_allocation here instead, but gdb_obstack.h specifies the allocation/deallocation functions. */ - obstack_init (&bcache->cache); + obstack_init (&m_cache); } /* If our average chain length is too high, expand the hash table. */ - if (bcache->unique_count >= bcache->num_buckets * CHAIN_LENGTH_THRESHOLD) - expand_hash_table (bcache); + if (m_unique_count >= m_num_buckets * CHAIN_LENGTH_THRESHOLD) + expand_hash_table (); - bcache->total_count++; - bcache->total_size += length; + m_total_count++; + m_total_size += length; - full_hash = bcache->hash_function (addr, length); + full_hash = m_hash_function (addr, length); half_hash = (full_hash >> 16); - hash_index = full_hash % bcache->num_buckets; + hash_index = full_hash % m_num_buckets; - /* Search the hash bucket for a string identical to the caller's. + /* Search the hash m_bucket for a string identical to the caller's. As a short-circuit first compare the upper part of each hash values. */ - for (s = bcache->bucket[hash_index]; s; s = s->next) + for (s = m_bucket[hash_index]; s; s = s->next) { if (s->half_hash == half_hash) { if (s->length == length - && bcache->compare_function (&s->d.data, addr, length)) + && m_compare_function (&s->d.data, addr, length)) return &s->d.data; else - bcache->half_hash_miss_count++; + m_half_hash_miss_count++; } } /* The user's string isn't in the list. Insert it after *ps. */ { struct bstring *newobj - = (struct bstring *) obstack_alloc (&bcache->cache, + = (struct bstring *) obstack_alloc (&m_cache, BSTRING_SIZE (length)); memcpy (&newobj->d.data, addr, length); newobj->length = length; - newobj->next = bcache->bucket[hash_index]; + newobj->next = m_bucket[hash_index]; newobj->half_hash = half_hash; - bcache->bucket[hash_index] = newobj; + m_bucket[hash_index] = newobj; - bcache->unique_count++; - bcache->unique_size += length; - bcache->structure_size += BSTRING_SIZE (length); + m_unique_count++; + m_unique_size += length; + m_structure_size += BSTRING_SIZE (length); if (added) *added = 1; @@ -289,51 +235,19 @@ bcache_full (const void *addr, int length, struct bcache *bcache, int *added) /* Compare the byte string at ADDR1 of lenght LENGHT to the string at ADDR2. Return 1 if they are equal. */ -static int -bcache_compare (const void *addr1, const void *addr2, int length) +int +bcache::compare (const void *addr1, const void *addr2, int length) { return memcmp (addr1, addr2, length) == 0; } -/* Allocating and freeing bcaches. */ - -/* Allocated a bcache. HASH_FUNCTION and COMPARE_FUNCTION can be used - to pass in custom hash, and compare functions to be used by this - bcache. If HASH_FUNCTION is NULL hash() is used and if - COMPARE_FUNCTION is NULL memcmp() is used. */ - -struct bcache * -bcache_xmalloc (unsigned long (*hash_function)(const void *, int length), - int (*compare_function)(const void *, - const void *, - int length)) -{ - /* Allocate the bcache pre-zeroed. */ - struct bcache *b = XCNEW (struct bcache); - - if (hash_function) - b->hash_function = hash_function; - else - b->hash_function = hash; - - if (compare_function) - b->compare_function = compare_function; - else - b->compare_function = bcache_compare; - return b; -} - /* Free all the storage associated with BCACHE. */ -void -bcache_xfree (struct bcache *bcache) +bcache::~bcache () { - if (bcache == NULL) - return; /* Only free the obstack if we actually initialized it. */ - if (bcache->total_count > 0) - obstack_free (&bcache->cache, 0); - xfree (bcache->bucket); - xfree (bcache); + if (m_total_count > 0) + obstack_free (&m_cache, 0); + xfree (m_bucket); } @@ -356,7 +270,7 @@ print_percentage (int portion, int total) BCACHE holds. Statistics are printed using `printf_filtered' and its ilk. */ void -print_bcache_statistics (struct bcache *c, const char *type) +bcache::print_statistics (const char *type) { int occupied_buckets; int max_chain_length; @@ -368,15 +282,15 @@ print_bcache_statistics (struct bcache *c, const char *type) lengths, and measure chain lengths. */ { unsigned int b; - int *chain_length = XCNEWVEC (int, c->num_buckets + 1); - int *entry_size = XCNEWVEC (int, c->unique_count + 1); + int *chain_length = XCNEWVEC (int, m_num_buckets + 1); + int *entry_size = XCNEWVEC (int, m_unique_count + 1); int stringi = 0; occupied_buckets = 0; - for (b = 0; b < c->num_buckets; b++) + for (b = 0; b < m_num_buckets; b++) { - struct bstring *s = c->bucket[b]; + struct bstring *s = m_bucket[b]; chain_length[b] = 0; @@ -386,9 +300,9 @@ print_bcache_statistics (struct bcache *c, const char *type) while (s) { - gdb_assert (b < c->num_buckets); + gdb_assert (b < m_num_buckets); chain_length[b]++; - gdb_assert (stringi < c->unique_count); + gdb_assert (stringi < m_unique_count); entry_size[stringi++] = s->length; s = s->next; } @@ -397,25 +311,25 @@ print_bcache_statistics (struct bcache *c, const char *type) /* To compute the median, we need the set of chain lengths sorted. */ - qsort (chain_length, c->num_buckets, sizeof (chain_length[0]), + qsort (chain_length, m_num_buckets, sizeof (chain_length[0]), compare_positive_ints); - qsort (entry_size, c->unique_count, sizeof (entry_size[0]), + qsort (entry_size, m_unique_count, sizeof (entry_size[0]), compare_positive_ints); - if (c->num_buckets > 0) + if (m_num_buckets > 0) { - max_chain_length = chain_length[c->num_buckets - 1]; - median_chain_length = chain_length[c->num_buckets / 2]; + max_chain_length = chain_length[m_num_buckets - 1]; + median_chain_length = chain_length[m_num_buckets / 2]; } else { max_chain_length = 0; median_chain_length = 0; } - if (c->unique_count > 0) + if (m_unique_count > 0) { - max_entry_size = entry_size[c->unique_count - 1]; - median_entry_size = entry_size[c->unique_count / 2]; + max_entry_size = entry_size[m_unique_count - 1]; + median_entry_size = entry_size[m_unique_count / 2]; } else { @@ -427,23 +341,23 @@ print_bcache_statistics (struct bcache *c, const char *type) xfree (entry_size); } - printf_filtered (_(" Cached '%s' statistics:\n"), type); - printf_filtered (_(" Total object count: %ld\n"), c->total_count); - printf_filtered (_(" Unique object count: %lu\n"), c->unique_count); + printf_filtered (_(" M_Cached '%s' statistics:\n"), type); + printf_filtered (_(" Total object count: %ld\n"), m_total_count); + printf_filtered (_(" Unique object count: %lu\n"), m_unique_count); printf_filtered (_(" Percentage of duplicates, by count: ")); - print_percentage (c->total_count - c->unique_count, c->total_count); + print_percentage (m_total_count - m_unique_count, m_total_count); printf_filtered ("\n"); - printf_filtered (_(" Total object size: %ld\n"), c->total_size); - printf_filtered (_(" Unique object size: %ld\n"), c->unique_size); + printf_filtered (_(" Total object size: %ld\n"), m_total_size); + printf_filtered (_(" Unique object size: %ld\n"), m_unique_size); printf_filtered (_(" Percentage of duplicates, by size: ")); - print_percentage (c->total_size - c->unique_size, c->total_size); + print_percentage (m_total_size - m_unique_size, m_total_size); printf_filtered ("\n"); printf_filtered (_(" Max entry size: %d\n"), max_entry_size); printf_filtered (_(" Average entry size: ")); - if (c->unique_count > 0) - printf_filtered ("%ld\n", c->unique_size / c->unique_count); + if (m_unique_count > 0) + printf_filtered ("%ld\n", m_unique_size / m_unique_count); else /* i18n: "Average entry size: (not applicable)". */ printf_filtered (_("(not applicable)\n")); @@ -452,28 +366,28 @@ print_bcache_statistics (struct bcache *c, const char *type) printf_filtered (_(" \ Total memory used by bcache, including overhead: %ld\n"), - c->structure_size); + m_structure_size); printf_filtered (_(" Percentage memory overhead: ")); - print_percentage (c->structure_size - c->unique_size, c->unique_size); + print_percentage (m_structure_size - m_unique_size, m_unique_size); printf_filtered (_(" Net memory savings: ")); - print_percentage (c->total_size - c->structure_size, c->total_size); + print_percentage (m_total_size - m_structure_size, m_total_size); printf_filtered ("\n"); printf_filtered (_(" Hash table size: %3d\n"), - c->num_buckets); + m_num_buckets); printf_filtered (_(" Hash table expands: %lu\n"), - c->expand_count); + m_expand_count); printf_filtered (_(" Hash table hashes: %lu\n"), - c->total_count + c->expand_hash_count); + m_total_count + m_expand_hash_count); printf_filtered (_(" Half hash misses: %lu\n"), - c->half_hash_miss_count); + m_half_hash_miss_count); printf_filtered (_(" Hash table population: ")); - print_percentage (occupied_buckets, c->num_buckets); + print_percentage (occupied_buckets, m_num_buckets); printf_filtered (_(" Median hash chain length: %3d\n"), median_chain_length); printf_filtered (_(" Average hash chain length: ")); - if (c->num_buckets > 0) - printf_filtered ("%3lu\n", c->unique_count / c->num_buckets); + if (m_num_buckets > 0) + printf_filtered ("%3lu\n", m_unique_count / m_num_buckets); else /* i18n: "Average hash chain length: (not applicable)". */ printf_filtered (_("(not applicable)\n")); @@ -483,9 +397,9 @@ Total memory used by bcache, including overhead: %ld\n"), } int -bcache_memory_used (struct bcache *bcache) +bcache::memory_used () { - if (bcache->total_count == 0) + if (m_total_count == 0) return 0; - return obstack_memory_used (&bcache->cache); + return obstack_memory_used (&m_cache); } diff --git a/gdb/bcache.h b/gdb/bcache.h index aa0147926c6..15dcc63440f 100644 --- a/gdb/bcache.h +++ b/gdb/bcache.h @@ -136,41 +136,89 @@ */ - -struct bcache; - -/* Find a copy of the LENGTH bytes at ADDR in BCACHE. If BCACHE has - never seen those bytes before, add a copy of them to BCACHE. In - either case, return a pointer to BCACHE's copy of that string. - Since the cached value is ment to be read-only, return a const - buffer. */ -extern const void *bcache (const void *addr, int length, - struct bcache *bcache); - -/* Like bcache, but if ADDED is not NULL, set *ADDED to true if the - bytes were newly added to the cache, or to false if the bytes were - found in the cache. */ -extern const void *bcache_full (const void *addr, int length, - struct bcache *bcache, int *added); - -/* Free all the storage used by BCACHE. */ -extern void bcache_xfree (struct bcache *bcache); - -/* Create a new bcache object. */ -extern struct bcache *bcache_xmalloc ( - unsigned long (*hash_function)(const void *, int length), - int (*compare_function)(const void *, const void *, int length)); - -/* Print statistics on BCACHE's memory usage and efficacity at - eliminating duplication. TYPE should be a string describing the - kind of data BCACHE holds. Statistics are printed using - `printf_filtered' and its ilk. */ -extern void print_bcache_statistics (struct bcache *bcache, const char *type); -extern int bcache_memory_used (struct bcache *bcache); +struct bstring; /* The hash functions */ -extern unsigned long hash(const void *addr, int length); +extern unsigned long hash (const void *addr, int length); extern unsigned long hash_continue (const void *addr, int length, unsigned long h); +struct bcache +{ + /* Allocate a bcache. HASH_FN and COMPARE_FN can be used to pass in + custom hash, and compare functions to be used by this bcache. If + HASH_FUNCTION is NULL hash() is used and if COMPARE_FUNCTION is + NULL memcmp() is used. */ + + explicit bcache (unsigned long (*hash_fn)(const void *, + int length) = nullptr, + int (*compare_fn)(const void *, const void *, + int length) = nullptr) + : m_hash_function (hash_fn == nullptr ? hash : hash_fn), + m_compare_function (compare_fn == nullptr ? compare : compare_fn) + { + } + + ~bcache (); + + /* Find a copy of the LENGTH bytes at ADDR in BCACHE. If BCACHE has + never seen those bytes before, add a copy of them to BCACHE. In + either case, return a pointer to BCACHE's copy of that string. + Since the cached value is ment to be read-only, return a const + buffer. If ADDED is not NULL, set *ADDED to true if the bytes + were newly added to the cache, or to false if the bytes were + found in the cache. */ + + const void *insert (const void *addr, int length, int *added = nullptr); + + /* Print statistics on this bcache's memory usage and efficacity at + eliminating duplication. TYPE should be a string describing the + kind of data this bcache holds. Statistics are printed using + `printf_filtered' and its ilk. */ + void print_statistics (const char *type); + int memory_used (); + +private: + + /* All the bstrings are allocated here. */ + struct obstack m_cache {}; + + /* How many hash buckets we're using. */ + unsigned int m_num_buckets = 0; + + /* Hash buckets. This table is allocated using malloc, so when we + grow the table we can return the old table to the system. */ + struct bstring **m_bucket = nullptr; + + /* Statistics. */ + unsigned long m_unique_count = 0; /* number of unique strings */ + long m_total_count = 0; /* total number of strings cached, including dups */ + long m_unique_size = 0; /* size of unique strings, in bytes */ + long m_total_size = 0; /* total number of bytes cached, including dups */ + long m_structure_size = 0; /* total size of bcache, including infrastructure */ + /* Number of times that the hash table is expanded and hence + re-built, and the corresponding number of times that a string is + [re]hashed as part of entering it into the expanded table. The + total number of hashes can be computed by adding TOTAL_COUNT to + expand_hash_count. */ + unsigned long m_expand_count = 0; + unsigned long m_expand_hash_count = 0; + /* Number of times that the half-hash compare hit (compare the upper + 16 bits of hash values) hit, but the corresponding combined + length/data compare missed. */ + unsigned long m_half_hash_miss_count = 0; + + /* Hash function to be used for this bcache object. */ + unsigned long (*m_hash_function)(const void *addr, int length); + + /* Compare function to be used for this bcache object. */ + int (*m_compare_function)(const void *, const void *, int length); + + /* Default compare function. */ + static int compare (const void *addr1, const void *addr2, int length); + + /* Expand the hash table. */ + void expand_hash_table (); +}; + #endif /* BCACHE_H */ diff --git a/gdb/buildsym.c b/gdb/buildsym.c index bd0f25e061e..9a23c8f5254 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -122,7 +122,7 @@ buildsym_compunit::get_macro_table () { if (m_pending_macros == nullptr) m_pending_macros = new_macro_table (&m_objfile->per_bfd->storage_obstack, - m_objfile->per_bfd->macro_cache, + &m_objfile->per_bfd->macro_cache, m_compunit_symtab); return m_pending_macros; } diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 2d6cb353fbb..0c59dcd2042 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -46,7 +46,6 @@ #include "macrotab.h" #include "language.h" #include "complaints.h" -#include "bcache.h" #include "dwarf2expr.h" #include "dwarf2loc.h" #include "cp-support.h" diff --git a/gdb/elfread.c b/gdb/elfread.c index 8fc6692b112..55a16bb2f8e 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -334,8 +334,8 @@ elf_symtab_read (minimal_symbol_reader &reader, if (sym->flags & BSF_FILE) { filesymname - = (const char *) bcache (sym->name, strlen (sym->name) + 1, - objfile->per_bfd->filename_cache); + = ((const char *) objfile->per_bfd->filename_cache.insert + (sym->name, strlen (sym->name) + 1)); } else if (sym->flags & BSF_SECTION_SYM) continue; diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index b5f269241c4..8e48587caa4 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -3732,7 +3732,7 @@ check_types_worklist (std::vector *worklist, /* If the type pair has already been visited, we know it is ok. */ - bcache_full (&entry, sizeof (entry), cache, &added); + cache->insert (&entry, sizeof (entry), &added); if (!added) continue; @@ -3749,9 +3749,6 @@ check_types_worklist (std::vector *worklist, bool types_deeply_equal (struct type *type1, struct type *type2) { - struct gdb_exception except = exception_none; - bool result = false; - struct bcache *cache; std::vector worklist; gdb_assert (type1 != NULL && type2 != NULL); @@ -3760,31 +3757,9 @@ types_deeply_equal (struct type *type1, struct type *type2) if (type1 == type2) return true; - cache = bcache_xmalloc (NULL, NULL); - + struct bcache cache (nullptr, nullptr); worklist.emplace_back (type1, type2); - - /* check_types_worklist calls several nested helper functions, some - of which can raise a GDB exception, so we just check and rethrow - here. If there is a GDB exception, a comparison is not capable - (or trusted), so exit. */ - TRY - { - result = check_types_worklist (&worklist, cache); - } - CATCH (ex, RETURN_MASK_ALL) - { - except = ex; - } - END_CATCH - - bcache_xfree (cache); - - /* Rethrow if there was a problem. */ - if (except.reason < 0) - throw_exception (except); - - return result; + return check_types_worklist (&worklist, &cache); } /* Allocated status of type TYPE. Return zero if type TYPE is allocated. diff --git a/gdb/macroexp.c b/gdb/macroexp.c index a588cc836fe..33a72a7271f 100644 --- a/gdb/macroexp.c +++ b/gdb/macroexp.c @@ -19,7 +19,6 @@ #include "defs.h" #include "gdb_obstack.h" -#include "bcache.h" #include "macrotab.h" #include "macroexp.h" #include "c-lang.h" diff --git a/gdb/macrotab.c b/gdb/macrotab.c index fa3061616bd..90f29439c09 100644 --- a/gdb/macrotab.c +++ b/gdb/macrotab.c @@ -113,7 +113,7 @@ static const void * macro_bcache (struct macro_table *t, const void *addr, int len) { if (t->bcache) - return bcache (addr, len, t->bcache); + return t->bcache->insert (addr, len); else { void *copy = xmalloc (len); diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 34b271e86de..4091b42dbf1 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -157,8 +157,6 @@ get_objfile_bfd_data (struct objfile *objfile, struct bfd *abfd) if (abfd != NULL) storage->gdbarch = gdbarch_from_bfd (abfd); - storage->filename_cache = bcache_xmalloc (NULL, NULL); - storage->macro_cache = bcache_xmalloc (NULL, NULL); storage->language_of_main = language_unknown; } @@ -170,8 +168,6 @@ get_objfile_bfd_data (struct objfile *objfile, struct bfd *abfd) static void free_objfile_per_bfd_storage (struct objfile_per_bfd_storage *storage) { - bcache_xfree (storage->filename_cache); - bcache_xfree (storage->macro_cache); if (storage->demangled_names_hash) htab_delete (storage->demangled_names_hash); storage->~objfile_per_bfd_storage (); diff --git a/gdb/objfiles.h b/gdb/objfiles.h index a10781f598e..c5ce9eec955 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -240,11 +240,11 @@ struct objfile_per_bfd_storage /* Byte cache for file names. */ - struct bcache *filename_cache = NULL; + struct bcache filename_cache; /* Byte cache for macros. */ - struct bcache *macro_cache = NULL; + struct bcache macro_cache; /* The gdbarch associated with the BFD. Note that this gdbarch is determined solely from BFD information, without looking at target diff --git a/gdb/psymtab.c b/gdb/psymtab.c index 17db29759c4..96b4fa0bf88 100644 --- a/gdb/psymtab.c +++ b/gdb/psymtab.c @@ -26,7 +26,6 @@ #include "source.h" #include "addrmap.h" #include "gdbtypes.h" -#include "bcache.h" #include "ui-out.h" #include "command.h" #include "readline/readline.h" @@ -38,11 +37,6 @@ #include #include -struct psymbol_bcache -{ - struct bcache *bcache; -}; - static struct partial_symbol *match_partial_symbol (struct objfile *, struct partial_symtab *, int, @@ -67,14 +61,16 @@ static struct compunit_symtab *psymtab_to_symtab (struct objfile *objfile, +static unsigned long psymbol_hash (const void *addr, int length); +static int psymbol_compare (const void *addr1, const void *addr2, int length); + psymtab_storage::psymtab_storage () - : psymbol_cache (psymbol_bcache_init ()) + : psymbol_cache (psymbol_hash, psymbol_compare) { } psymtab_storage::~psymtab_storage () { - psymbol_bcache_free (psymbol_cache); } /* See psymtab.h. */ @@ -1589,52 +1585,6 @@ psymbol_compare (const void *addr1, const void *addr2, int length) && sym1->name == sym2->name); } -/* Initialize a partial symbol bcache. */ - -struct psymbol_bcache * -psymbol_bcache_init (void) -{ - struct psymbol_bcache *bcache = XCNEW (struct psymbol_bcache); - - bcache->bcache = bcache_xmalloc (psymbol_hash, psymbol_compare); - return bcache; -} - -/* Free a partial symbol bcache. */ - -void -psymbol_bcache_free (struct psymbol_bcache *bcache) -{ - if (bcache == NULL) - return; - - bcache_xfree (bcache->bcache); - xfree (bcache); -} - -/* Return the internal bcache of the psymbol_bcache BCACHE. */ - -struct bcache * -psymbol_bcache_get_bcache (struct psymbol_bcache *bcache) -{ - return bcache->bcache; -} - -/* Find a copy of the SYM in BCACHE. If BCACHE has never seen this - symbol before, add a copy to BCACHE. In either case, return a pointer - to BCACHE's copy of the symbol. If optional ADDED is not NULL, return - 1 in case of new entry or 0 if returning an old entry. */ - -static struct partial_symbol * -psymbol_bcache_full (struct partial_symbol *sym, - struct psymbol_bcache *bcache, - int *added) -{ - return ((struct partial_symbol *) - bcache_full (sym, sizeof (struct partial_symbol), bcache->bcache, - added)); -} - /* Helper function, initialises partial symbol structure and stashes it into objfile's bcache. Note that our caching mechanism will use all fields of struct partial_symbol to determine hash value of the @@ -1664,9 +1614,9 @@ add_psymbol_to_bcache (const char *name, int namelength, int copy_name, symbol_set_names (&psymbol, name, namelength, copy_name, objfile->per_bfd); /* Stash the partial symbol away in the cache. */ - return psymbol_bcache_full (&psymbol, - objfile->partial_symtabs->psymbol_cache, - added); + return ((struct partial_symbol *) + objfile->partial_symtabs->psymbol_cache.insert + (&psymbol, sizeof (struct partial_symbol), added)); } /* Helper function, adds partial symbol to the given partial symbol list. */ @@ -1741,8 +1691,8 @@ allocate_psymtab (const char *filename, struct objfile *objfile) = objfile->partial_symtabs->allocate_psymtab (); psymtab->filename - = (const char *) bcache (filename, strlen (filename) + 1, - objfile->per_bfd->filename_cache); + = ((const char *) objfile->per_bfd->filename_cache.insert + (filename, strlen (filename) + 1)); psymtab->compunit_symtab = NULL; if (symtab_create_debug) diff --git a/gdb/psymtab.h b/gdb/psymtab.h index 3ee5eee0b65..c761fa72222 100644 --- a/gdb/psymtab.h +++ b/gdb/psymtab.h @@ -23,13 +23,10 @@ #include "gdb_obstack.h" #include "symfile.h" #include "common/next-iterator.h" +#include "bcache.h" struct partial_symbol; -/* A bcache for partial symbols. */ - -struct psymbol_bcache; - /* An instance of this class manages the partial symbol tables and partial symbols for a given objfile. @@ -119,7 +116,7 @@ public: /* A byte cache where we can stash arbitrary "chunks" of bytes that will not change. */ - struct psymbol_bcache *psymbol_cache; + struct bcache psymbol_cache; /* Vectors of all partial symbols read in from file. The actual data is stored in the objfile_obstack. */ @@ -140,10 +137,6 @@ private: }; -extern struct psymbol_bcache *psymbol_bcache_init (void); -extern void psymbol_bcache_free (struct psymbol_bcache *); -extern struct bcache *psymbol_bcache_get_bcache (struct psymbol_bcache *); - extern const struct quick_symbol_functions psym_functions; extern const struct quick_symbol_functions dwarf2_gdb_index_functions; diff --git a/gdb/stabsread.c b/gdb/stabsread.c index ac33465c13b..3f340dbf20d 100644 --- a/gdb/stabsread.c +++ b/gdb/stabsread.c @@ -44,7 +44,6 @@ #include "target-float.h" #include "cp-abi.h" #include "cp-support.h" -#include "bcache.h" #include #include "stabsread.h" diff --git a/gdb/symfile.c b/gdb/symfile.c index 61483824f63..2214f16b431 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -2795,8 +2795,8 @@ allocate_symtab (struct compunit_symtab *cust, const char *filename) = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symtab); symtab->filename - = (const char *) bcache (filename, strlen (filename) + 1, - objfile->per_bfd->filename_cache); + = ((const char *) objfile->per_bfd->filename_cache.insert + (filename, strlen (filename) + 1)); symtab->fullname = NULL; symtab->language = deduce_language_from_filename (filename); diff --git a/gdb/symmisc.c b/gdb/symmisc.c index bb4fdfd1ed9..cb0b5a52e47 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -69,13 +69,11 @@ print_symbol_bcache_statistics (void) QUIT; printf_filtered (_("Byte cache statistics for '%s':\n"), objfile_name (objfile)); - print_bcache_statistics - (psymbol_bcache_get_bcache (objfile->partial_symtabs->psymbol_cache), - "partial symbol cache"); - print_bcache_statistics (objfile->per_bfd->macro_cache, - "preprocessor macro cache"); - print_bcache_statistics (objfile->per_bfd->filename_cache, - "file name cache"); + objfile->partial_symtabs->psymbol_cache.print_statistics + ("partial symbol cache"); + objfile->per_bfd->macro_cache.print_statistics + ("preprocessor macro cache"); + objfile->per_bfd->filename_cache.print_statistics ("file name cache"); } } @@ -136,12 +134,11 @@ print_objfile_statistics (void) ->storage_obstack))); printf_filtered (_(" Total memory used for psymbol cache: %d\n"), - bcache_memory_used (psymbol_bcache_get_bcache - (objfile->partial_symtabs->psymbol_cache))); + objfile->partial_symtabs->psymbol_cache.memory_used ()); printf_filtered (_(" Total memory used for macro cache: %d\n"), - bcache_memory_used (objfile->per_bfd->macro_cache)); + objfile->per_bfd->macro_cache.memory_used ()); printf_filtered (_(" Total memory used for file name cache: %d\n"), - bcache_memory_used (objfile->per_bfd->filename_cache)); + objfile->per_bfd->filename_cache.memory_used ()); } }