Fix crash when creating index from index
[binutils-gdb.git] / gdb / bcache.c
index 3f0a63be229f08d82ebf65a8df2e685ff52288df..80ba1f6b6ecc037fc430411ddf19ea7b8b56652c 100644 (file)
@@ -2,7 +2,7 @@
    Written by Fred Fish <fnf@cygnus.com>
    Rewritten by Jim Blandy <jimb@cygnus.com>
 
-   Copyright (C) 1999-2019 Free Software Foundation, Inc.
+   Copyright (C) 1999-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include "gdb_obstack.h"
+#include "gdbsupport/gdb_obstack.h"
 #include "bcache.h"
 
 #include <algorithm>
 
+namespace gdb {
+
 /* The type used to hold a single bcache string.  The user data is
    stored in d.data.  Since it can be any type, it needs to have the
    same alignment as the most strict alignment of any type on the host
@@ -51,31 +53,6 @@ struct bstring
   d;
 };
 
-/* The old hash function was stolen from SDBM. This is what DB 3.0
-   uses now, and is better than the old one.  */
-\f
-unsigned long
-hash(const void *addr, int length)
-{
-  return hash_continue (addr, length, 0);
-}
-
-/* Continue the calculation of the hash H at the given address.  */
-
-unsigned long
-hash_continue (const void *addr, int length, unsigned long h)
-{
-  const unsigned char *k, *e;
-
-  k = (const unsigned char *)addr;
-  e = k+length;
-  for (; k< e;++k)
-    {
-      h *=16777619;
-      h ^= *k;
-    }
-  return (h);
-}
 \f
 /* Growing the bcache's hash table.  */
 
@@ -91,7 +68,7 @@ bcache::expand_hash_table ()
      so we roughly double the table size each time.  After we fall off 
      the end of this table, we just double.  Don't laugh --- there have
      been executables sighted with a gigabyte of debug info.  */
-  static unsigned long sizes[] = { 
+  static const unsigned long sizes[] = {
     1021, 2053, 4099, 8191, 16381, 32771,
     65537, 131071, 262144, 524287, 1048573, 2097143,
     4194301, 8388617, 16777213, 33554467, 67108859, 134217757,
@@ -108,10 +85,10 @@ bcache::expand_hash_table ()
 
   /* Find the next size.  */
   new_num_buckets = m_num_buckets * 2;
-  for (i = 0; i < (sizeof (sizes) / sizeof (sizes[0])); i++)
-    if (sizes[i] > m_num_buckets)
+  for (unsigned long a_size : sizes)
+    if (a_size > m_num_buckets)
       {
-       new_num_buckets = sizes[i];
+       new_num_buckets = a_size;
        break;
       }
 
@@ -136,7 +113,7 @@ bcache::expand_hash_table ()
          struct bstring **new_bucket;
          next = s->next;
 
-         new_bucket = &new_buckets[(m_hash_function (&s->d.data, s->length)
+         new_bucket = &new_buckets[(this->hash (&s->d.data, s->length)
                                     % new_num_buckets)];
          s->next = *new_bucket;
          *new_bucket = s;
@@ -163,15 +140,15 @@ bcache::expand_hash_table ()
    returning an old entry.  */
 
 const void *
-bcache::insert (const void *addr, int length, int *added)
+bcache::insert (const void *addr, int length, bool *added)
 {
   unsigned long full_hash;
   unsigned short half_hash;
   int hash_index;
   struct bstring *s;
 
-  if (added)
-    *added = 0;
+  if (added != nullptr)
+    *added = false;
 
   /* Lazily initialize the obstack.  This can save quite a bit of
      memory in some cases.  */
@@ -190,7 +167,7 @@ bcache::insert (const void *addr, int length, int *added)
   m_total_count++;
   m_total_size += length;
 
-  full_hash = m_hash_function (addr, length);
+  full_hash = this->hash (addr, length);
 
   half_hash = (full_hash >> 16);
   hash_index = full_hash % m_num_buckets;
@@ -203,7 +180,7 @@ bcache::insert (const void *addr, int length, int *added)
       if (s->half_hash == half_hash)
        {
          if (s->length == length
-             && m_compare_function (&s->d.data, addr, length))
+             && this->compare (&s->d.data, addr, length))
            return &s->d.data;
          else
            m_half_hash_miss_count++;
@@ -226,21 +203,28 @@ bcache::insert (const void *addr, int length, int *added)
     m_unique_size += length;
     m_structure_size += BSTRING_SIZE (length);
 
-    if (added)
-      *added = 1;
+    if (added != nullptr)
+      *added = true;
 
     return &newobj->d.data;
   }
 }
 \f
 
-/* Compare the byte string at ADDR1 of lenght LENGHT to the
-   string at ADDR2.  Return 1 if they are equal.  */
+/* See bcache.h.  */
+
+unsigned long
+bcache::hash (const void *addr, int length)
+{
+  return fast_hash (addr, length, 0);
+}
+
+/* See bcache.h.  */
 
 int
-bcache::compare (const void *addr1, const void *addr2, int length)
+bcache::compare (const void *left, const void *right, int length)
 {
-  return memcmp (addr1, addr2, length) == 0;
+  return memcmp (left, right, length) == 0;
 }
 
 /* Free all the storage associated with BCACHE.  */
@@ -261,15 +245,15 @@ print_percentage (int portion, int total)
 {
   if (total == 0)
     /* i18n: Like "Percentage of duplicates, by count: (not applicable)".  */
-    printf_filtered (_("(not applicable)\n"));
+    gdb_printf (_("(not applicable)\n"));
   else
-    printf_filtered ("%3d%%\n", (int) (portion * 100.0 / total));
+    gdb_printf ("%3d%%\n", (int) (portion * 100.0 / total));
 }
 
 
 /* Print statistics on BCACHE's memory usage and efficacity at
    eliminating duplication.  NAME should describe the kind of data
-   BCACHE holds.  Statistics are printed using `printf_filtered' and
+   BCACHE holds.  Statistics are printed using `gdb_printf' and
    its ilk.  */
 void
 bcache::print_statistics (const char *type)
@@ -341,59 +325,59 @@ bcache::print_statistics (const char *type)
     xfree (entry_size);
   }
 
-  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: "));
+  gdb_printf (_("  M_Cached '%s' statistics:\n"), type);
+  gdb_printf (_("    Total object count:  %ld\n"), m_total_count);
+  gdb_printf (_("    Unique object count: %lu\n"), m_unique_count);
+  gdb_printf (_("    Percentage of duplicates, by count: "));
   print_percentage (m_total_count - m_unique_count, m_total_count);
-  printf_filtered ("\n");
+  gdb_printf ("\n");
 
-  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:  "));
+  gdb_printf (_("    Total object size:   %ld\n"), m_total_size);
+  gdb_printf (_("    Unique object size:  %ld\n"), m_unique_size);
+  gdb_printf (_("    Percentage of duplicates, by size:  "));
   print_percentage (m_total_size - m_unique_size, m_total_size);
-  printf_filtered ("\n");
+  gdb_printf ("\n");
 
-  printf_filtered (_("    Max entry size:     %d\n"), max_entry_size);
-  printf_filtered (_("    Average entry size: "));
+  gdb_printf (_("    Max entry size:     %d\n"), max_entry_size);
+  gdb_printf (_("    Average entry size: "));
   if (m_unique_count > 0)
-    printf_filtered ("%ld\n", m_unique_size / m_unique_count);
+    gdb_printf ("%ld\n", m_unique_size / m_unique_count);
   else
     /* i18n: "Average entry size: (not applicable)".  */
-    printf_filtered (_("(not applicable)\n"));    
-  printf_filtered (_("    Median entry size:  %d\n"), median_entry_size);
-  printf_filtered ("\n");
+    gdb_printf (_("(not applicable)\n"));    
+  gdb_printf (_("    Median entry size:  %d\n"), median_entry_size);
+  gdb_printf ("\n");
 
-  printf_filtered (_("    \
+  gdb_printf (_("    \
 Total memory used by bcache, including overhead: %ld\n"),
-                  m_structure_size);
-  printf_filtered (_("    Percentage memory overhead: "));
+             m_structure_size);
+  gdb_printf (_("    Percentage memory overhead: "));
   print_percentage (m_structure_size - m_unique_size, m_unique_size);
-  printf_filtered (_("    Net memory savings:         "));
+  gdb_printf (_("    Net memory savings:         "));
   print_percentage (m_total_size - m_structure_size, m_total_size);
-  printf_filtered ("\n");
-
-  printf_filtered (_("    Hash table size:           %3d\n"), 
-                  m_num_buckets);
-  printf_filtered (_("    Hash table expands:        %lu\n"),
-                  m_expand_count);
-  printf_filtered (_("    Hash table hashes:         %lu\n"),
-                  m_total_count + m_expand_hash_count);
-  printf_filtered (_("    Half hash misses:          %lu\n"),
-                  m_half_hash_miss_count);
-  printf_filtered (_("    Hash table population:     "));
+  gdb_printf ("\n");
+
+  gdb_printf (_("    Hash table size:           %3d\n"), 
+             m_num_buckets);
+  gdb_printf (_("    Hash table expands:        %lu\n"),
+             m_expand_count);
+  gdb_printf (_("    Hash table hashes:         %lu\n"),
+             m_total_count + m_expand_hash_count);
+  gdb_printf (_("    Half hash misses:          %lu\n"),
+             m_half_hash_miss_count);
+  gdb_printf (_("    Hash table population:     "));
   print_percentage (occupied_buckets, m_num_buckets);
-  printf_filtered (_("    Median hash chain length:  %3d\n"),
-                  median_chain_length);
-  printf_filtered (_("    Average hash chain length: "));
+  gdb_printf (_("    Median hash chain length:  %3d\n"),
+             median_chain_length);
+  gdb_printf (_("    Average hash chain length: "));
   if (m_num_buckets > 0)
-    printf_filtered ("%3lu\n", m_unique_count / m_num_buckets);
+    gdb_printf ("%3lu\n", m_unique_count / m_num_buckets);
   else
     /* i18n: "Average hash chain length: (not applicable)".  */
-    printf_filtered (_("(not applicable)\n"));
-  printf_filtered (_("    Maximum hash chain length: %3d\n"), 
-                  max_chain_length);
-  printf_filtered ("\n");
+    gdb_printf (_("(not applicable)\n"));
+  gdb_printf (_("    Maximum hash chain length: %3d\n"), 
+             max_chain_length);
+  gdb_printf ("\n");
 }
 
 int
@@ -403,3 +387,5 @@ bcache::memory_used ()
     return 0;
   return obstack_memory_used (&m_cache);
 }
+
+} /* namespace gdb */