aboutsummaryrefslogtreecommitdiff
path: root/gdb/bcache.c
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2019-03-07 04:20:19 -0700
committerTom Tromey <tom@tromey.com>2019-03-07 10:48:02 -0700
commit25629dfdb438c82f2bb711174042bb326a526aaf (patch)
treef0bd8f98faa31b5124de5963abe119507a095622 /gdb/bcache.c
parentfe7266674110f34eacf2e9d2b308f76d33ce50ed (diff)
downloadgdb-25629dfdb438c82f2bb711174042bb326a526aaf.zip
gdb-25629dfdb438c82f2bb711174042bb326a526aaf.tar.gz
gdb-25629dfdb438c82f2bb711174042bb326a526aaf.tar.bz2
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 <tom@tromey.com> * 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) <psymbol_cache>: 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) <filename_cache, macro_cache>: 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.
Diffstat (limited to 'gdb/bcache.c')
-rw-r--r--gdb/bcache.c238
1 files changed, 76 insertions, 162 deletions
diff --git a/gdb/bcache.c b/gdb/bcache.c
index 1430953..14a7847 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;
}
@@ -201,21 +156,12 @@ expand_hash_table (struct bcache *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. */
-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
optional ADDED is not NULL, return 1 in case of new entry or 0 if
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);
}