2002-07-11 Daniel Jacobowitz <drow@mvista.com>
authorDaniel Jacobowitz <drow@false.org>
Thu, 11 Jul 2002 20:46:19 +0000 (20:46 +0000)
committerDaniel Jacobowitz <drow@false.org>
Thu, 11 Jul 2002 20:46:19 +0000 (20:46 +0000)
Based on patch from Daniel Berlin <dberlin@dberlin.org>.
* buildsym.c: Include "demangle.h" for SYMBOL_INIT_DEMANGLED_NAME.
(finish_block) For non-function blocks, hash the symbol table.  For
function blocks, mark the symbol table as unhashed.
* minsyms.c (msymbol_hash): Return hash value without taking modulus.
(msymbol_hash_iw): Likewise.
(add_minsym_to_hash_table): Take modulus of msymbol_hash's return
value.
(add_minsym_to_demangled_hash_table): Likewise for msymbol_hash_iw.
(lookup_minimal_symbol): Likewise for both.
* symtab.h (struct block): Add `hashtable' flag.  Comment the
hashtable.
(BLOCK_HASHTABLE, BLOCK_BUCKETS, BLOCK_BUCKET): New macro.
(ALL_BLOCK_SYMBOLS): Update.
(BLOCK_SHOULD_SORT): Do not sort hashed blocks.
(struct symbol): Add `hash_next' pointer.
* symtab.c (lookup_block_symbol): Search using the hash table when
possible.
(find_pc_sect_symtab): Use ALL_BLOCK_SYMBOLS.
(search_symbols, find_addr_symbol): Likewise.

* dstread.c (process_dst_block): Clear hashtable bit for new block.
(read_dst_symtab): Likewise.
* jv-lang.c (get_java_class_symtab): Likewise.
* mdebugread.c: Include "gdb_assert.h".
(shrink_block): Assert that the block being modified is not hashed.
* coffread.c (patch_opaque_types): Use ALL_BLOCK_SYMBOLS.
* symmisc.c (free_symtab_block): Walk the hash table when freeing
symbols.
(dump_symtab): Recognize hashed blocks.
* printcmd.c (print_frame_args):  Assert that function blocks do not
have hashed symbol tables.
* ada-lang.c (symtab_for_sym): Use ALL_BLOCK_SYMBOLS.
(fill_in_ada_prototype, debug_print_block): Likewise.
(ada_add_block_symbols): Use ALL_BLOCK_SYMBOLS.  Handle hash tables.

12 files changed:
gdb/ChangeLog
gdb/ada-lang.c
gdb/buildsym.c
gdb/coffread.c
gdb/dstread.c
gdb/jv-lang.c
gdb/mdebugread.c
gdb/minsyms.c
gdb/printcmd.c
gdb/symmisc.c
gdb/symtab.c
gdb/symtab.h

index 686d16ff439fc0ae5e4c812f68e415a92e716878..6a5d9a35f121e8ff3de6c3e13ec627b830656f0a 100644 (file)
@@ -1,3 +1,41 @@
+2002-07-11  Daniel Jacobowitz  <drow@mvista.com>
+
+       Based on patch from Daniel Berlin <dberlin@dberlin.org>.
+       * buildsym.c: Include "demangle.h" for SYMBOL_INIT_DEMANGLED_NAME.
+       (finish_block) For non-function blocks, hash the symbol table.  For
+       function blocks, mark the symbol table as unhashed.
+       * minsyms.c (msymbol_hash): Return hash value without taking modulus.
+       (msymbol_hash_iw): Likewise.
+       (add_minsym_to_hash_table): Take modulus of msymbol_hash's return
+       value.
+       (add_minsym_to_demangled_hash_table): Likewise for msymbol_hash_iw.
+       (lookup_minimal_symbol): Likewise for both.
+       * symtab.h (struct block): Add `hashtable' flag.  Comment the
+       hashtable.
+       (BLOCK_HASHTABLE, BLOCK_BUCKETS, BLOCK_BUCKET): New macro.
+       (ALL_BLOCK_SYMBOLS): Update.
+       (BLOCK_SHOULD_SORT): Do not sort hashed blocks.
+       (struct symbol): Add `hash_next' pointer.
+       * symtab.c (lookup_block_symbol): Search using the hash table when
+       possible.
+       (find_pc_sect_symtab): Use ALL_BLOCK_SYMBOLS.
+       (search_symbols, find_addr_symbol): Likewise.
+
+       * dstread.c (process_dst_block): Clear hashtable bit for new block.
+       (read_dst_symtab): Likewise.
+       * jv-lang.c (get_java_class_symtab): Likewise.
+       * mdebugread.c: Include "gdb_assert.h".
+       (shrink_block): Assert that the block being modified is not hashed.
+       * coffread.c (patch_opaque_types): Use ALL_BLOCK_SYMBOLS.
+       * symmisc.c (free_symtab_block): Walk the hash table when freeing
+       symbols.
+       (dump_symtab): Recognize hashed blocks.
+       * printcmd.c (print_frame_args):  Assert that function blocks do not
+       have hashed symbol tables.
+       * ada-lang.c (symtab_for_sym): Use ALL_BLOCK_SYMBOLS.
+       (fill_in_ada_prototype, debug_print_block): Likewise.
+       (ada_add_block_symbols): Use ALL_BLOCK_SYMBOLS.  Handle hash tables.
+
 2002-07-11  Corinna Vinschen  <vinschen@redhat.com>
 
        * stack.c (print_frame): Use result of frame_address_in_block()
index db1d7d4f185ac3912bb713ca5c21e53caf36e092..feb5a68bf37994c547a8115996f94849ba643d6e 100644 (file)
@@ -3560,6 +3560,7 @@ symtab_for_sym (sym)
   struct symtab* s;
   struct objfile *objfile;
   struct block *b;
+  struct symbol *tmp_sym;
   int i, j;
 
   ALL_SYMTABS (objfile, s)
@@ -3574,12 +3575,12 @@ symtab_for_sym (sym)
        case LOC_BLOCK:
        case LOC_CONST_BYTES:
          b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
-         for (i = 0; i < BLOCK_NSYMS (b); i += 1)
-           if (sym == BLOCK_SYM (b, i))
+         ALL_BLOCK_SYMBOLS (b, i, tmp_sym)
+           if (sym == tmp_sym)
              return s;
          b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
-         for (i = 0; i < BLOCK_NSYMS (b); i += 1)
-           if (sym == BLOCK_SYM (b, i))
+         ALL_BLOCK_SYMBOLS (b, i, tmp_sym)
+           if (sym == tmp_sym)
              return s;
          break;
        default:
@@ -3601,8 +3602,8 @@ symtab_for_sym (sym)
               j < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (s)); j += 1)
            {
              b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), j);
-             for (i = 0; i < BLOCK_NSYMS (b); i += 1)
-               if (sym == BLOCK_SYM (b, i))
+             ALL_BLOCK_SYMBOLS (b, i, tmp_sym)
+               if (sym == tmp_sym)
                  return s;
            }
          break;
@@ -4094,14 +4095,14 @@ ada_add_block_symbols (block, name, namespace, objfile, wild)
   /* Set true when we find a matching non-argument symbol */
   int found_sym;
   int is_sorted = BLOCK_SHOULD_SORT (block);
+  struct symbol *sym;
 
   arg_sym = NULL; found_sym = 0;
   if (wild)
     {
-      for (i = 0; i < BLOCK_NSYMS (block); i += 1)
+      struct symbol *sym;
+      ALL_BLOCK_SYMBOLS (block, i, sym)
        {
-         struct symbol *sym = BLOCK_SYM (block, i);
-
          if (SYMBOL_NAMESPACE (sym) == namespace &&
              wild_match (name, name_len, SYMBOL_NAME (sym)))
            {
@@ -4149,44 +4150,46 @@ ada_add_block_symbols (block, name, namespace, objfile, wild)
       else
        i = 0;
 
-      for (; i < BLOCK_NSYMS (block); i += 1)
-       {
-         struct symbol *sym = BLOCK_SYM (block, i);
+      for (; i < BLOCK_BUCKETS (block); i += 1)
+       for (sym = BLOCK_BUCKET (block, i); sym != NULL; sym = sym->hash_next)
+         {
+           if (SYMBOL_NAMESPACE (sym) == namespace)
+             {
+               int cmp = strncmp (name, SYMBOL_NAME (sym), name_len);
 
-         if (SYMBOL_NAMESPACE (sym) == namespace)
-           {
-             int cmp = strncmp (name, SYMBOL_NAME (sym), name_len);
-       
-             if (cmp < 0) 
-               {
-                 if (is_sorted)
-                   break;
-               }
-             else if (cmp == 0 
-                      && is_name_suffix (SYMBOL_NAME (sym) + name_len)) 
-               {
-                 switch (SYMBOL_CLASS (sym))
-                   {
-                   case LOC_ARG:
-                   case LOC_LOCAL_ARG:
-                   case LOC_REF_ARG:
-                   case LOC_REGPARM:
-                   case LOC_REGPARM_ADDR:
-                   case LOC_BASEREG_ARG:
-                     arg_sym = sym;
-                     break;
-                   case LOC_UNRESOLVED:
-                     break;
-                   default:
-                     found_sym = 1;
-                     fill_in_ada_prototype (sym);
-                     add_defn_to_vec (fixup_symbol_section (sym, objfile),
-                                      block);
-                     break;
-                   }
-               }
-           }
-       }
+               if (cmp < 0) 
+                 {
+                   if (is_sorted)
+                     {
+                       i = BLOCK_BUCKETS (block);
+                       break;
+                     }
+                 }
+               else if (cmp == 0 
+                        && is_name_suffix (SYMBOL_NAME (sym) + name_len)) 
+                 {
+                   switch (SYMBOL_CLASS (sym))
+                     {
+                     case LOC_ARG:
+                     case LOC_LOCAL_ARG:
+                     case LOC_REF_ARG:
+                     case LOC_REGPARM:
+                     case LOC_REGPARM_ADDR:
+                     case LOC_BASEREG_ARG:
+                       arg_sym = sym;
+                       break;
+                     case LOC_UNRESOLVED:
+                       break;
+                     default:
+                       found_sym = 1;
+                       fill_in_ada_prototype (sym);
+                       add_defn_to_vec (fixup_symbol_section (sym, objfile),
+                                        block);
+                       break;
+                     }
+                 }
+             }
+         }
     }
 
   if (! found_sym && arg_sym != NULL)
@@ -4219,53 +4222,57 @@ ada_add_block_symbols (block, name, namespace, objfile, wild)
       else
        i = 0;
 
-      for (; i < BLOCK_NSYMS (block); i += 1)
-       {
-         struct symbol *sym = BLOCK_SYM (block, i);
+      for (; i < BLOCK_BUCKETS (block); i += 1)
+       for (sym = BLOCK_BUCKET (block, i); sym != NULL; sym = sym->hash_next)
+         {
+           struct symbol *sym = BLOCK_SYM (block, i);
 
-         if (SYMBOL_NAMESPACE (sym) == namespace)
-           {
-             int cmp;
+           if (SYMBOL_NAMESPACE (sym) == namespace)
+             {
+               int cmp;
 
-             cmp = (int) '_' - (int) SYMBOL_NAME (sym)[0];
-             if (cmp == 0) 
-               {
-                 cmp = strncmp ("_ada_", SYMBOL_NAME (sym), 5);
-                 if (cmp == 0)
-                   cmp = strncmp (name, SYMBOL_NAME (sym) + 5, name_len);
-               }
-       
-             if (cmp < 0) 
-               {
-                 if (is_sorted)
-                   break;
-               }
-             else if (cmp == 0 
-                      && is_name_suffix (SYMBOL_NAME (sym) + name_len + 5)) 
-               {
-                 switch (SYMBOL_CLASS (sym))
-                   {
-                   case LOC_ARG:
-                   case LOC_LOCAL_ARG:
-                   case LOC_REF_ARG:
-                   case LOC_REGPARM:
-                   case LOC_REGPARM_ADDR:
-                   case LOC_BASEREG_ARG:
-                     arg_sym = sym;
-                     break;
-                   case LOC_UNRESOLVED:
-                     break;
-                   default:
-                     found_sym = 1;
-                     fill_in_ada_prototype (sym);
-                     add_defn_to_vec (fixup_symbol_section (sym, objfile),
-                                      block);
-                     break;
-                   }
-               }
-           }
-       }
-      
+               cmp = (int) '_' - (int) SYMBOL_NAME (sym)[0];
+               if (cmp == 0) 
+                 {
+                   cmp = strncmp ("_ada_", SYMBOL_NAME (sym), 5);
+                   if (cmp == 0)
+                     cmp = strncmp (name, SYMBOL_NAME (sym) + 5, name_len);
+                 }
+
+               if (cmp < 0) 
+                 {
+                   if (is_sorted)
+                     {
+                       i = BLOCK_BUCKETS (block);
+                       break;
+                     }
+                 }
+               else if (cmp == 0 
+                        && is_name_suffix (SYMBOL_NAME (sym) + name_len + 5)) 
+                 {
+                   switch (SYMBOL_CLASS (sym))
+                     {
+                     case LOC_ARG:
+                     case LOC_LOCAL_ARG:
+                     case LOC_REF_ARG:
+                     case LOC_REGPARM:
+                     case LOC_REGPARM_ADDR:
+                     case LOC_BASEREG_ARG:
+                       arg_sym = sym;
+                       break;
+                     case LOC_UNRESOLVED:
+                       break;
+                     default:
+                       found_sym = 1;
+                       fill_in_ada_prototype (sym);
+                       add_defn_to_vec (fixup_symbol_section (sym, objfile),
+                                        block);
+                       break;
+                     }
+                 }
+             }
+         }
+  
       /* NOTE: This really shouldn't be needed for _ada_ symbols.
         They aren't parameters, right? */
       if (! found_sym && arg_sym != NULL)
@@ -4292,6 +4299,7 @@ fill_in_ada_prototype (func)
   struct type* ftype;
   struct type* rtype;
   size_t max_fields;
+  struct symbol *sym;
 
   if (func == NULL
       || TYPE_CODE (SYMBOL_TYPE (func)) != TYPE_CODE_FUNC
@@ -4308,16 +4316,13 @@ fill_in_ada_prototype (func)
   SYMBOL_TYPE (func) = ftype;
 
   b = SYMBOL_BLOCK_VALUE (func);
-  nsyms = BLOCK_NSYMS (b);
 
   nargs = 0;
   max_fields = 8; 
   TYPE_FIELDS (ftype) = 
     (struct field*) xmalloc (sizeof (struct field) * max_fields);
-  for (i = 0; i < nsyms; i += 1)
+  ALL_BLOCK_SYMBOLS (b, i, sym)
     {
-      struct symbol *sym = BLOCK_SYM (b, i);
-
       GROW_VECT (TYPE_FIELDS (ftype), max_fields, nargs+1);
        
       switch (SYMBOL_CLASS (sym)) 
@@ -4903,6 +4908,8 @@ debug_print_block (b)
      struct block* b;
 {
   int i;
+  struct symbol *i;
+
   fprintf (stderr, "Block: %p; [0x%lx, 0x%lx]", 
           b, BLOCK_START(b), BLOCK_END(b));
   if (BLOCK_FUNCTION(b) != NULL)
@@ -4910,11 +4917,11 @@ debug_print_block (b)
   fprintf (stderr, "\n");
   fprintf (stderr, "\t    Superblock: %p\n", BLOCK_SUPERBLOCK(b));
   fprintf (stderr, "\t    Symbols:");
-  for (i = 0; i < BLOCK_NSYMS (b); i += 1)
+  ALL_BLOCK_SYMBOLS (b, i, sym)
     {
       if (i > 0 && i % 4 == 0)
        fprintf (stderr, "\n\t\t    ");
-      fprintf (stderr, " %s", SYMBOL_NAME (BLOCK_SYM (b, i)));
+      fprintf (stderr, " %s", SYMBOL_NAME (sym));
     }
   fprintf (stderr, "\n");
 }
index 5078935fefebb98e2eb2615bb904857fb0bcae54..f62ecad70d2efa394babad7e07aa3dabdcbf9ffe 100644 (file)
@@ -40,6 +40,7 @@
 #include "bcache.h"
 #include "filenames.h"         /* For DOSish file names */
 #include "macrotab.h"
+#include "demangle.h"          /* Needed by SYMBOL_INIT_DEMANGLED_NAME.  */
 /* Ask buildsym.h to define the vars it normally declares `extern'.  */
 #define        EXTERN
 /**/
@@ -243,17 +244,49 @@ finish_block (struct symbol *symbol, struct pending **listhead,
       /* EMPTY */ ;
     }
 
-  block = (struct block *) obstack_alloc (&objfile->symbol_obstack,
-           (sizeof (struct block) + ((i - 1) * sizeof (struct symbol *))));
-
   /* Copy the symbols into the block.  */
 
-  BLOCK_NSYMS (block) = i;
-  for (next = *listhead; next; next = next->next)
+  if (symbol)
+    {
+      block = (struct block *) 
+       obstack_alloc (&objfile->symbol_obstack,
+                      (sizeof (struct block) + 
+                       ((i - 1) * sizeof (struct symbol *))));
+      BLOCK_NSYMS (block) = i;
+      for (next = *listhead; next; next = next->next)
+       for (j = next->nsyms - 1; j >= 0; j--)
+         {
+           BLOCK_SYM (block, --i) = next->symbol[j];
+         }
+    }
+  else
     {
-      for (j = next->nsyms - 1; j >= 0; j--)
+      int htab_size = BLOCK_HASHTABLE_SIZE (i);
+
+      block = (struct block *) 
+       obstack_alloc (&objfile->symbol_obstack,
+                      (sizeof (struct block) + 
+                       ((htab_size - 1) * sizeof (struct symbol *))));
+      for (j = 0; j < htab_size; j++)
+       {
+         BLOCK_BUCKET (block, j) = 0;
+       }
+      BLOCK_BUCKETS (block) = htab_size;
+      for (next = *listhead; next; next = next->next)
        {
-         BLOCK_SYM (block, --i) = next->symbol[j];
+         for (j = next->nsyms - 1; j >= 0; j--)
+           {
+             struct symbol *sym;
+             unsigned int hash_index;
+             const char *name = SYMBOL_DEMANGLED_NAME (next->symbol[j]);
+             if (name == NULL)
+               name = SYMBOL_NAME (next->symbol[j]);
+             hash_index = msymbol_hash_iw (name);
+             hash_index = hash_index % BLOCK_BUCKETS (block);
+             sym = BLOCK_BUCKET (block, hash_index);
+             BLOCK_BUCKET (block, hash_index) = next->symbol[j];
+             next->symbol[j]->hash_next = sym;
+           }
        }
     }
 
@@ -271,6 +304,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
       struct type *ftype = SYMBOL_TYPE (symbol);
       SYMBOL_BLOCK_VALUE (symbol) = block;
       BLOCK_FUNCTION (block) = symbol;
+      BLOCK_HASHTABLE (block) = 0;
 
       if (TYPE_NFIELDS (ftype) <= 0)
        {
@@ -352,6 +386,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
   else
     {
       BLOCK_FUNCTION (block) = NULL;
+      BLOCK_HASHTABLE (block) = 1;
     }
 
   /* Now "free" the links of the list, and empty the list.  */
index 84b3761cf55e7c0fc75c8d03c07fd13aaead2f07..bd18b4acb0742d38b6cbfedd5ba41552fa963f09 100644 (file)
@@ -1409,13 +1409,12 @@ patch_opaque_types (struct symtab *s)
 
   /* Go through the per-file symbols only */
   b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
-  for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--)
+  ALL_BLOCK_SYMBOLS (b, i, real_sym)
     {
       /* Find completed typedefs to use to fix opaque ones.
          Remove syms from the chain when their types are stored,
          but search the whole chain, as there may be several syms
          from different files with the same name.  */
-      real_sym = BLOCK_SYM (b, i);
       if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF &&
          SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE &&
          TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&
index abcce097a2743b327db8c10860cb462489dfc472..82e5e9c5bef72adb1e1a5e095fd4c765c7087b58 100644 (file)
@@ -1396,6 +1396,7 @@ process_dst_block (struct objfile *objfile, dst_rec_ptr_t entry)
       symnum++;
     }
   BLOCK_NSYMS (block) = total_symbols;
+  BLOCK_HASHTABLE (block) = 0;
   BLOCK_START (block) = address;
   BLOCK_END (block) = address + size;
   BLOCK_SUPERBLOCK (block) = 0;
@@ -1480,6 +1481,7 @@ read_dst_symtab (struct objfile *objfile)
                             (total_globals - 1) *
                           sizeof (struct symbol *));
          BLOCK_NSYMS (global_block) = total_globals;
+         BLOCK_HASHTABLE (global_block) = 0;
          for (symnum = 0; symnum < total_globals; symnum++)
            {
              nextsym = dst_global_symbols->next;
index e221105ed6ff3e58c7764af5f820a269cf8f4090..3afdebdb46727fdbe622493f1c4c167d525a66da 100644 (file)
@@ -106,6 +106,7 @@ get_java_class_symtab (void)
       bl = (struct block *)
        obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
       BLOCK_NSYMS (bl) = 0;
+      BLOCK_HASHTABLE (bl) = 0;
       BLOCK_START (bl) = 0;
       BLOCK_END (bl) = 0;
       BLOCK_FUNCTION (bl) = NULL;
index 14d2c0f753ebf76441579a5ed25a33a407252551..3f32e4cdb43c27b518240566457f6d2efcf851d6 100644 (file)
@@ -52,6 +52,7 @@
 #include "stabsread.h"
 #include "complaints.h"
 #include "demangle.h"
+#include "gdb_assert.h"
 
 /* These are needed if the tm.h file does not contain the necessary
    mips specific definitions.  */
@@ -4727,6 +4728,11 @@ shrink_block (struct block *b, struct symtab *s)
                                    + ((BLOCK_NSYMS (b) - 1)
                                       * sizeof (struct symbol *))));
 
+  /* FIXME: Not worth hashing this block as it's built.  */
+  /* All callers should have created the block with new_block (), which
+     would mean it was not previously hashed.  Make sure.  */
+  gdb_assert (BLOCK_HASHTABLE (new) == 0);
+
   /* Should chase pointers to old one.  Fortunately, that`s just
      the block`s function and inferior blocks */
   if (BLOCK_FUNCTION (new) && SYMBOL_BLOCK_VALUE (BLOCK_FUNCTION (new)) == b)
index 4fa1d911f08fcd3b76732d042afac5d3df74717f..b1ef28ffa5feae4140a01a55fed1f713eaa5fede 100644 (file)
@@ -91,7 +91,7 @@ msymbol_hash_iw (const char *string)
          ++string;
        }
     }
-  return hash % MINIMAL_SYMBOL_HASH_SIZE;
+  return hash;
 }
 
 /* Compute a hash code for a string.  */
@@ -102,7 +102,7 @@ msymbol_hash (const char *string)
   unsigned int hash = 0;
   for (; *string; ++string)
     hash = hash * 67 + *string - 113;
-  return hash % MINIMAL_SYMBOL_HASH_SIZE;
+  return hash;
 }
 
 /* Add the minimal symbol SYM to an objfile's minsym hash table, TABLE.  */
@@ -112,7 +112,7 @@ add_minsym_to_hash_table (struct minimal_symbol *sym,
 {
   if (sym->hash_next == NULL)
     {
-      unsigned int hash = msymbol_hash (SYMBOL_NAME (sym));
+      unsigned int hash = msymbol_hash (SYMBOL_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE;
       sym->hash_next = table[hash];
       table[hash] = sym;
     }
@@ -126,7 +126,7 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
 {
   if (sym->demangled_hash_next == NULL)
     {
-      unsigned int hash = msymbol_hash_iw (SYMBOL_DEMANGLED_NAME (sym));
+      unsigned int hash = msymbol_hash_iw (SYMBOL_DEMANGLED_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE;
       sym->demangled_hash_next = table[hash];
       table[hash] = sym;
     }
@@ -154,8 +154,8 @@ lookup_minimal_symbol (register const char *name, const char *sfile,
   struct minimal_symbol *found_file_symbol = NULL;
   struct minimal_symbol *trampoline_symbol = NULL;
 
-  unsigned int hash = msymbol_hash (name);
-  unsigned int dem_hash = msymbol_hash_iw (name);
+  unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
+  unsigned int dem_hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE;
 
 #ifdef SOFUN_ADDRESS_MAYBE_MISSING
   if (sfile != NULL)
index de306f0b98fbf6495510681f24577c5f47c64ad8..2e57050105f04d1a4dbb89316d7bb40bc67ddb7a 100644 (file)
@@ -40,6 +40,7 @@
 #include "objfiles.h"          /* ditto */
 #include "completer.h"         /* for completion functions */
 #include "ui-out.h"
+#include "gdb_assert.h"
 
 extern int asm_demangle;       /* Whether to demangle syms in asm printouts */
 extern int addressprint;       /* Whether to print hex addresses in HLL " */
@@ -1785,6 +1786,10 @@ print_frame_args (struct symbol *func, struct frame_info *fi, int num,
   if (func)
     {
       b = SYMBOL_BLOCK_VALUE (func);
+      /* Function blocks are order sensitive, and thus should not be
+        hashed.  */
+      gdb_assert (BLOCK_HASHTABLE (b) == 0);
+
       ALL_BLOCK_SYMBOLS (b, i, sym)
         {
          QUIT;
index 39b10a6a02cf6afea7d08facd90abd42a8b3d4c8..370b76e1aa5335f14dd213c356543a6ba7b6e91b 100644 (file)
@@ -86,11 +86,17 @@ static void
 free_symtab_block (struct objfile *objfile, struct block *b)
 {
   register int i, n;
-  n = BLOCK_NSYMS (b);
+  struct symbol *sym, *next_sym;
+
+  n = BLOCK_BUCKETS (b);
   for (i = 0; i < n; i++)
     {
-      xmfree (objfile->md, SYMBOL_NAME (BLOCK_SYM (b, i)));
-      xmfree (objfile->md, (PTR) BLOCK_SYM (b, i));
+      for (sym = BLOCK_BUCKET (b, i); sym; sym = next_sym)
+       {
+         next_sym = sym->hash_next;
+         xmfree (objfile->md, SYMBOL_NAME (sym));
+         xmfree (objfile->md, (PTR) sym);
+       }
     }
   xmfree (objfile->md, (PTR) b);
 }
@@ -457,8 +463,14 @@ dump_symtab (struct objfile *objfile, struct symtab *symtab,
              fprintf_filtered (outfile, " under ");
              gdb_print_host_address (BLOCK_SUPERBLOCK (b), outfile);
            }
-         blen = BLOCK_NSYMS (b);
-         fprintf_filtered (outfile, ", %d syms in ", blen);
+         /* drow/2002-07-10: We could save the total symbols count
+            even if we're using a hashtable, but nothing else but this message
+            wants it.  */
+         blen = BLOCK_BUCKETS (b);
+         if (BLOCK_HASHTABLE (b))
+           fprintf_filtered (outfile, ", %d buckets in ", blen);
+         else
+           fprintf_filtered (outfile, ", %d syms in ", blen);
          print_address_numeric (BLOCK_START (b), 1, outfile);
          fprintf_filtered (outfile, "..");
          print_address_numeric (BLOCK_END (b), 1, outfile);
@@ -474,8 +486,8 @@ dump_symtab (struct objfile *objfile, struct symtab *symtab,
          if (BLOCK_GCC_COMPILED (b))
            fprintf_filtered (outfile, ", compiled with gcc%d", BLOCK_GCC_COMPILED (b));
          fprintf_filtered (outfile, "\n");
-         /* Now print each symbol in this block.  */
-         /* FIXMED: Sort?  */
+         /* Now print each symbol in this block (in no particular order, if
+            we're using a hashtable).  */
          ALL_BLOCK_SYMBOLS (b, j, sym)
            {
              struct print_symbol_args s;
index 334e0ec5cdbd9405c13baf2f3864b857da111978..89730915e31297466a0c323da2b1f4497f6726d0 100644 (file)
@@ -1328,6 +1328,22 @@ lookup_block_symbol (register const struct block *block, const char *name,
   register struct symbol *sym_found = NULL;
   register int do_linear_search = 1;
 
+  if (BLOCK_HASHTABLE (block))
+    {
+      unsigned int hash_index;
+      hash_index = msymbol_hash_iw (name);
+      hash_index = hash_index % BLOCK_BUCKETS (block);
+      for (sym = BLOCK_BUCKET (block, hash_index); sym; sym = sym->hash_next)
+       {
+         if (SYMBOL_NAMESPACE (sym) == namespace 
+             && (mangled_name
+                 ? strcmp (SYMBOL_NAME (sym), mangled_name) == 0
+                 : SYMBOL_MATCHES_NAME (sym, name)))
+           return sym;
+       }
+      return NULL;
+    }
+
   /* If the blocks's symbols were sorted, start with a binary search.  */
 
   if (BLOCK_SHOULD_SORT (block))
@@ -1582,14 +1598,15 @@ find_pc_sect_symtab (CORE_ADDR pc, asection *section)
        if (section != 0)
          {
            int i;
+           struct symbol *sym = NULL;
 
-           for (i = 0; i < b->nsyms; i++)
+           ALL_BLOCK_SYMBOLS (b, i, sym)
              {
-               fixup_symbol_section (b->sym[i], objfile);
-               if (section == SYMBOL_BFD_SECTION (b->sym[i]))
+               fixup_symbol_section (sym, objfile);
+               if (section == SYMBOL_BFD_SECTION (sym))
                  break;
              }
-           if (i >= b->nsyms)
+           if ((i >= BLOCK_BUCKETS (b)) && (sym == NULL))
              continue;         /* no symbol in this symtab matches section */
          }
        distance = BLOCK_END (b) - BLOCK_START (b);
@@ -1661,10 +1678,8 @@ find_addr_symbol (CORE_ADDR addr, struct symtab **symtabp, CORE_ADDR *symaddrp)
       {
        QUIT;
        block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), blocknum);
-       top = BLOCK_NSYMS (block);
-       for (bot = 0; bot < top; bot++)
+       ALL_BLOCK_SYMBOLS (block, bot, sym)
          {
-           sym = BLOCK_SYM (block, bot);
            switch (SYMBOL_CLASS (sym))
              {
              case LOC_STATIC:
@@ -2795,10 +2810,9 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
          struct symbol_search *prevtail = tail;
          int nfound = 0;
          b = BLOCKVECTOR_BLOCK (bv, i);
-         for (j = 0; j < BLOCK_NSYMS (b); j++)
+         ALL_BLOCK_SYMBOLS (b, j, sym)
            {
              QUIT;
-             sym = BLOCK_SYM (b, j);
              if (file_matches (s->filename, files, nfiles)
                  && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym))
                      && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (sym) != LOC_TYPEDEF
index 713dd0dfe4e603e7d3db04f746fb928847473e38..6ea5538f65b54c0eb5b5a07955126b32a433a187 100644 (file)
@@ -386,6 +386,25 @@ struct block
 
     unsigned char gcc_compile_flag;
 
+    /* The symbols for this block are either in a simple linear list or
+       in a simple hashtable.  Blocks which correspond to a function
+       (which have a list of symbols corresponding to arguments) use
+       a linear list, as do some older symbol readers (currently only
+       mdebugread and dstread).  Other blocks are hashed.
+
+       The hashtable uses the same hash function as the minsym hashtables,
+       found in minsyms.c:minsym_hash_iw.  Symbols are hashed based on
+       their demangled name if appropriate, and on their name otherwise.
+       The hash function ignores space, and stops at the beginning of the
+       argument list if any.
+
+       The table is laid out in NSYMS/5 buckets and symbols are chained via
+       their hash_next field.  */
+
+    /* If this is really a hashtable of the symbols, this flag is 1.  */
+
+    unsigned char hashtable;
+
     /* Number of local symbols.  */
 
     int nsyms;
@@ -398,30 +417,38 @@ struct block
 
 #define BLOCK_START(bl)                (bl)->startaddr
 #define BLOCK_END(bl)          (bl)->endaddr
-#define BLOCK_NSYMS(bl)                (bl)->nsyms
-#define BLOCK_SYM(bl, n)       (bl)->sym[n]
 #define BLOCK_FUNCTION(bl)     (bl)->function
 #define BLOCK_SUPERBLOCK(bl)   (bl)->superblock
 #define BLOCK_GCC_COMPILED(bl) (bl)->gcc_compile_flag
+#define BLOCK_HASHTABLE(bl)    (bl)->hashtable
 
-/* Macro to loop through all symbols in a block BL.
-   i counts which symbol we are looking at, and sym points to the current
-   symbol.
-   The contortion at the end is to avoid reading past the last valid
-   BLOCK_SYM.  */
-#define ALL_BLOCK_SYMBOLS(bl, i, sym)                  \
-       for ((i) = 0, (sym) = BLOCK_SYM ((bl), (i));    \
-            (i) < BLOCK_NSYMS ((bl));                  \
-            ++(i), (sym) = ((i) < BLOCK_NSYMS ((bl)))  \
-                           ? BLOCK_SYM ((bl), (i))     \
-                           : NULL)
+/* For blocks without a hashtable (BLOCK_HASHTABLE (bl) == 0) only.  */
+#define BLOCK_NSYMS(bl)                (bl)->nsyms
+#define BLOCK_SYM(bl, n)       (bl)->sym[n]
+
+/* For blocks with a hashtable, but these are valid for non-hashed blocks as
+   well - each symbol will appear to be one bucket by itself.  */
+#define BLOCK_BUCKETS(bl)      (bl)->nsyms
+#define BLOCK_BUCKET(bl, n)    (bl)->sym[n]
+
+/* Macro used to set the size of a hashtable for N symbols.  */
+#define BLOCK_HASHTABLE_SIZE(n)        ((n)/5 + 1)
+
+/* Macro to loop through all symbols in a block BL, in no particular order.
+   i counts which bucket we are in, and sym points to the current symbol.  */
+
+#define ALL_BLOCK_SYMBOLS(bl, i, sym)                          \
+       for ((i) = 0; (i) < BLOCK_BUCKETS ((bl)); (i)++)        \
+         for ((sym) = BLOCK_BUCKET ((bl), (i)); (sym);         \
+              (sym) = (sym)->hash_next)
 
 /* Nonzero if symbols of block BL should be sorted alphabetically.
    Don't sort a block which corresponds to a function.  If we did the
    sorting would have to preserve the order of the symbols for the
-   arguments.  */
+   arguments.  Also don't sort any block that we chose to hash.  */
 
-#define BLOCK_SHOULD_SORT(bl) ((bl)->nsyms >= 40 && BLOCK_FUNCTION (bl) == NULL)
+#define BLOCK_SHOULD_SORT(bl) (! BLOCK_HASHTABLE (bl) \
+                              && BLOCK_FUNCTION (bl) == NULL)
 \f
 
 /* Represent one symbol name; a variable, constant, function or typedef.  */
@@ -671,6 +698,8 @@ struct symbol
     /* List of ranges where this symbol is active.  This is only
        used by alias symbols at the current time.  */
     struct range_list *ranges;
+
+    struct symbol *hash_next;
   };