2005-05-17 Daniel Jacobowitz <dan@codesourcery.com>
[deliverable/binutils-gdb.git] / gas / hash.c
index 2faeba9c091db72335d5fd6dceed1f1302f186b0..0f4742a5b02ead3cd967334b3ba67d0f1a70f31f 100644 (file)
@@ -1,6 +1,6 @@
 /* hash.c -- gas hash table code
    Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
-   2000, 2001, 2002
+   2000, 2001, 2002, 2003, 2005
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -17,8 +17,8 @@
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to the Free
-   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
 /* This version of the hash table code is a wholescale replacement of
    the old hash table code, which was fairly bad.  This is based on
 #include "safe-ctype.h"
 #include "obstack.h"
 
-/* The default number of entries to use when creating a hash table.  */
-
-#define DEFAULT_SIZE (4051)
-
 /* An entry in a hash table.  */
 
 struct hash_entry {
@@ -72,21 +68,55 @@ struct hash_control {
 #endif /* HASH_STATISTICS */
 };
 
+/* The default number of entries to use when creating a hash table.
+   Note this value can be reduced to 4051 by using the command line
+   switch --reduce-memory-overheads, or set to other values by using
+   the --hash-size=<NUMBER> switch.  */
+
+static unsigned long gas_hash_table_size = 65537;
+
+void
+set_gas_hash_table_size (unsigned long size)
+{
+  gas_hash_table_size = size;
+}
+
+/* FIXME: This function should be amalgmated with bfd/hash.c:bfd_hash_set_default_size().  */
+static unsigned long
+get_gas_hash_table_size (void)
+{
+  /* Extend this prime list if you want more granularity of hash table size.  */
+  static const unsigned long hash_size_primes[] =
+    {
+      1021, 4051, 8599, 16699, 65537
+    };
+  unsigned int index;
+
+  /* Work out the best prime number near the hash_size.
+     FIXME: This could be a more sophisticated algorithm,
+     but is it really worth implementing it ?   */
+  for (index = 0; index < ARRAY_SIZE (hash_size_primes) - 1; ++index)
+    if (gas_hash_table_size <= hash_size_primes[index])
+      break;
+
+  return hash_size_primes[index];
+}
+
 /* Create a hash table.  This return a control block.  */
 
 struct hash_control *
-hash_new ()
+hash_new (void)
 {
-  unsigned int size;
+  unsigned long size;
+  unsigned long alloc;
   struct hash_control *ret;
-  unsigned int alloc;
 
-  size = DEFAULT_SIZE;
+  size = get_gas_hash_table_size ();
 
-  ret = (struct hash_control *) xmalloc (sizeof *ret);
+  ret = xmalloc (sizeof *ret);
   obstack_begin (&ret->memory, chunksize);
   alloc = size * sizeof (struct hash_entry *);
-  ret->table = (struct hash_entry **) obstack_alloc (&ret->memory, alloc);
+  ret->table = obstack_alloc (&ret->memory, alloc);
   memset (ret->table, 0, alloc);
   ret->size = size;
 
@@ -105,8 +135,7 @@ hash_new ()
 /* Delete a hash table, freeing all allocated memory.  */
 
 void
-hash_die (table)
-     struct hash_control *table;
+hash_die (struct hash_control *table)
 {
   obstack_free (&table->memory, 0);
   free (table);
@@ -121,17 +150,14 @@ hash_die (table)
    Each time we look up a string, we move it to the start of the list
    for its hash code, to take advantage of referential locality.  */
 
-static struct hash_entry *hash_lookup PARAMS ((struct hash_control *,
-                                              const char *,
-                                              struct hash_entry ***,
-                                              unsigned long *));
+static struct hash_entry *hash_lookup (struct hash_control *,
+                                      const char *,
+                                      struct hash_entry ***,
+                                      unsigned long *);
 
 static struct hash_entry *
-hash_lookup (table, key, plist, phash)
-     struct hash_control *table;
-     const char *key;
-     struct hash_entry ***plist;
-     unsigned long *phash;
+hash_lookup (struct hash_control *table, const char *key,
+            struct hash_entry ***plist, unsigned long *phash)
 {
   register unsigned long hash;
   unsigned int len;
@@ -205,10 +231,7 @@ hash_lookup (table, key, plist, phash)
    hash table.  */
 
 const char *
-hash_insert (table, key, value)
-     struct hash_control *table;
-     const char *key;
-     PTR value;
+hash_insert (struct hash_control *table, const char *key, PTR value)
 {
   struct hash_entry *p;
   struct hash_entry **list;
@@ -238,10 +261,7 @@ hash_insert (table, key, value)
    error.  If an entry already exists, its value is replaced.  */
 
 const char *
-hash_jam (table, key, value)
-     struct hash_control *table;
-     const char *key;
-     PTR value;
+hash_jam (struct hash_control *table, const char *key, PTR value)
 {
   struct hash_entry *p;
   struct hash_entry **list;
@@ -279,10 +299,7 @@ hash_jam (table, key, value)
    table, this does nothing and returns NULL.  */
 
 PTR
-hash_replace (table, key, value)
-     struct hash_control *table;
-     const char *key;
-     PTR value;
+hash_replace (struct hash_control *table, const char *key, PTR value)
 {
   struct hash_entry *p;
   PTR ret;
@@ -306,9 +323,7 @@ hash_replace (table, key, value)
    if the entry is not found.  */
 
 PTR
-hash_find (table, key)
-     struct hash_control *table;
-     const char *key;
+hash_find (struct hash_control *table, const char *key)
 {
   struct hash_entry *p;
 
@@ -323,9 +338,7 @@ hash_find (table, key)
    for that entry, or NULL if there is no such entry.  */
 
 PTR
-hash_delete (table, key)
-     struct hash_control *table;
-     const char *key;
+hash_delete (struct hash_control *table, const char *key)
 {
   struct hash_entry *p;
   struct hash_entry **list;
@@ -354,9 +367,8 @@ hash_delete (table, key)
    hash table.  */
 
 void
-hash_traverse (table, pfn)
-     struct hash_control *table;
-     void (*pfn) PARAMS ((const char *key, PTR value));
+hash_traverse (struct hash_control *table,
+              void (*pfn) (const char *key, PTR value))
 {
   unsigned int i;
 
@@ -373,10 +385,9 @@ hash_traverse (table, pfn)
    name of the hash table, used for printing a header.  */
 
 void
-hash_print_statistics (f, name, table)
-     FILE *f ATTRIBUTE_UNUSED;
-     const char *name ATTRIBUTE_UNUSED;
-     struct hash_control *table ATTRIBUTE_UNUSED;
+hash_print_statistics (FILE *f ATTRIBUTE_UNUSED,
+                      const char *name ATTRIBUTE_UNUSED,
+                      struct hash_control *table ATTRIBUTE_UNUSED)
 {
 #ifdef HASH_STATISTICS
   unsigned int i;
This page took 0.029479 seconds and 4 git commands to generate.