2005-05-09 Kelley Cook <kcook@gcc.gnu.org>
[deliverable/binutils-gdb.git] / gas / hash.c
index 14ff25ee9d3e20ed6074626343396c57076bca88..0f4742a5b02ead3cd967334b3ba67d0f1a70f31f 100644 (file)
@@ -1,5 +1,6 @@
 /* hash.c -- gas hash table code
-   Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 98, 99, 2000
+   Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
+   2000, 2001, 2002, 2003, 2005
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
    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
    the hash table code in BFD, but optimized slightly for the
-   asssembler.  The assembler does not need to derive structures that
+   assembler.  The assembler does not need to derive structures that
    are stored in the hash table.  Instead, it always stores a pointer.
    The assembler uses the hash table mostly to store symbols, and we
    don't need to confuse the symbol structure with a hash table
    structure.  */
 
 #include "as.h"
+#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
-{
+struct hash_entry {
   /* Next entry for this hash code.  */
   struct hash_entry *next;
   /* String being hashed.  */
@@ -52,8 +49,7 @@ struct hash_entry
 
 /* A hash table.  */
 
-struct hash_control
-{
+struct hash_control {
   /* The hash array.  */
   struct hash_entry **table;
   /* The number of slots in the hash table.  */
@@ -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;
 
@@ -99,14 +129,13 @@ hash_new ()
   ret->deletions = 0;
 #endif
 
-  return ret;  
+  return ret;
 }
 
 /* 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;
@@ -222,7 +245,7 @@ hash_insert (table, key, value)
   ++table->insertions;
 #endif
 
-  p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof(*p));
+  p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof (*p));
   p->string = key;
   p->hash = hash;
   p->data = value;
@@ -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;
@@ -262,7 +282,7 @@ hash_jam (table, key, value)
       ++table->insertions;
 #endif
 
-      p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof(*p));
+      p = (struct hash_entry *) obstack_alloc (&table->memory, sizeof (*p));
       p->string = key;
       p->hash = hash;
       p->data = value;
@@ -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;
@@ -415,14 +426,23 @@ hash_print_statistics (f, name, table)
 
 /* This test program is left over from the old hash table code.  */
 
-#define TABLES (6)             /* number of hash tables to maintain */
-                               /* (at once) in any testing */
-#define STATBUFSIZE (12)       /* we can have 12 statistics */
+/* Number of hash tables to maintain (at once) in any testing.  */
+#define TABLES (6)
+
+/* We can have 12 statistics.  */
+#define STATBUFSIZE (12)
 
-int statbuf[STATBUFSIZE];      /* display statistics here */
-char answer[100];              /* human farts here */
-char *hashtable[TABLES];       /* we test many hash tables at once */
-char *h;                       /* points to curent hash_control */
+/* Display statistics here.  */
+int statbuf[STATBUFSIZE];
+
+/* Human farts here.  */
+char answer[100];
+
+/* We test many hash tables at once.  */
+char *hashtable[TABLES];
+
+/* Points to current hash_control.  */
+char *h;
 char **pp;
 char *p;
 char *name;
@@ -430,8 +450,9 @@ char *value;
 int size;
 int used;
 char command;
-int number;                    /* number 0:TABLES-1 of current hashed */
-                               /* symbol table */
+
+/* Number 0:TABLES-1 of current hashed symbol table.  */
+int number;
 
 int
 main ()
@@ -449,8 +470,7 @@ main ()
       printf ("hash_test command: ");
       gets (answer);
       command = answer[0];
-      if (isupper (command))
-       command = tolower (command);    /* ecch! */
+      command = TOLOWER (command);     /* Ecch!  */
       switch (command)
        {
        case '#':
@@ -460,8 +480,8 @@ main ()
        case '?':
          for (pp = hashtable; pp < hashtable + TABLES; pp++)
            {
-             printf ("address of hash table #%d control block is %xx\n"
-                     ,pp - hashtable, *pp);
+             printf ("address of hash table #%d control block is %xx\n",
+                     pp - hashtable, *pp);
            }
          break;
        case 'a':
@@ -537,19 +557,9 @@ char *
 what (description)
      char *description;
 {
-  char *retval;
-  char *malloc ();
-
   printf ("   %s : ", description);
   gets (answer);
-  /* will one day clean up answer here */
-  retval = malloc (strlen (answer) + 1);
-  if (!retval)
-    {
-      error ("room");
-    }
-  (void) strcpy (retval, answer);
-  return (retval);
+  return xstrdup (answer);
 }
 
 void
@@ -561,7 +571,6 @@ destroy (string, value)
   free (value);
 }
 
-
 void
 applicatee (string, value)
      char *string;
@@ -570,11 +579,12 @@ applicatee (string, value)
   printf ("%.20s-%.20s\n", string, value);
 }
 
+/* Determine number: what hash table to use.
+   Also determine h: points to hash_control.  */
+
 void
-whattable ()                   /* determine number: what hash table to use */
-                               /* also determine h: points to hash_control */
+whattable ()
 {
-
   for (;;)
     {
       printf ("   what hash table (%d:%d) ?  ", 0, TABLES - 1);
@@ -596,6 +606,4 @@ whattable ()                        /* determine number: what hash table to use */
     }
 }
 
-#endif /* #ifdef TEST */
-
-/* end of hash.c */
+#endif /* TEST */
This page took 0.029425 seconds and 4 git commands to generate.