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.
This commit is contained in:
Daniel Jacobowitz 2002-07-11 20:46:19 +00:00
parent 7c1f909cd5
commit 261397f84f
12 changed files with 291 additions and 143 deletions

View 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> 2002-07-11 Corinna Vinschen <vinschen@redhat.com>
* stack.c (print_frame): Use result of frame_address_in_block() * stack.c (print_frame): Use result of frame_address_in_block()

View file

@ -3560,6 +3560,7 @@ symtab_for_sym (sym)
struct symtab* s; struct symtab* s;
struct objfile *objfile; struct objfile *objfile;
struct block *b; struct block *b;
struct symbol *tmp_sym;
int i, j; int i, j;
ALL_SYMTABS (objfile, s) ALL_SYMTABS (objfile, s)
@ -3574,12 +3575,12 @@ symtab_for_sym (sym)
case LOC_BLOCK: case LOC_BLOCK:
case LOC_CONST_BYTES: case LOC_CONST_BYTES:
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
for (i = 0; i < BLOCK_NSYMS (b); i += 1) ALL_BLOCK_SYMBOLS (b, i, tmp_sym)
if (sym == BLOCK_SYM (b, i)) if (sym == tmp_sym)
return s; return s;
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
for (i = 0; i < BLOCK_NSYMS (b); i += 1) ALL_BLOCK_SYMBOLS (b, i, tmp_sym)
if (sym == BLOCK_SYM (b, i)) if (sym == tmp_sym)
return s; return s;
break; break;
default: default:
@ -3601,8 +3602,8 @@ symtab_for_sym (sym)
j < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (s)); j += 1) j < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (s)); j += 1)
{ {
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), j); b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), j);
for (i = 0; i < BLOCK_NSYMS (b); i += 1) ALL_BLOCK_SYMBOLS (b, i, tmp_sym)
if (sym == BLOCK_SYM (b, i)) if (sym == tmp_sym)
return s; return s;
} }
break; break;
@ -4094,14 +4095,14 @@ ada_add_block_symbols (block, name, namespace, objfile, wild)
/* Set true when we find a matching non-argument symbol */ /* Set true when we find a matching non-argument symbol */
int found_sym; int found_sym;
int is_sorted = BLOCK_SHOULD_SORT (block); int is_sorted = BLOCK_SHOULD_SORT (block);
struct symbol *sym;
arg_sym = NULL; found_sym = 0; arg_sym = NULL; found_sym = 0;
if (wild) 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 && if (SYMBOL_NAMESPACE (sym) == namespace &&
wild_match (name, name_len, SYMBOL_NAME (sym))) wild_match (name, name_len, SYMBOL_NAME (sym)))
{ {
@ -4149,44 +4150,46 @@ ada_add_block_symbols (block, name, namespace, objfile, wild)
else else
i = 0; i = 0;
for (; i < BLOCK_NSYMS (block); i += 1) 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 = strncmp (name, SYMBOL_NAME (sym), name_len);
if (SYMBOL_NAMESPACE (sym) == namespace) if (cmp < 0)
{ {
int cmp = strncmp (name, SYMBOL_NAME (sym), name_len); if (is_sorted)
{
if (cmp < 0) i = BLOCK_BUCKETS (block);
{ break;
if (is_sorted) }
break; }
} else if (cmp == 0
else if (cmp == 0 && is_name_suffix (SYMBOL_NAME (sym) + name_len))
&& is_name_suffix (SYMBOL_NAME (sym) + name_len)) {
{ switch (SYMBOL_CLASS (sym))
switch (SYMBOL_CLASS (sym)) {
{ case LOC_ARG:
case LOC_ARG: case LOC_LOCAL_ARG:
case LOC_LOCAL_ARG: case LOC_REF_ARG:
case LOC_REF_ARG: case LOC_REGPARM:
case LOC_REGPARM: case LOC_REGPARM_ADDR:
case LOC_REGPARM_ADDR: case LOC_BASEREG_ARG:
case LOC_BASEREG_ARG: arg_sym = sym;
arg_sym = sym; break;
break; case LOC_UNRESOLVED:
case LOC_UNRESOLVED: break;
break; default:
default: found_sym = 1;
found_sym = 1; fill_in_ada_prototype (sym);
fill_in_ada_prototype (sym); add_defn_to_vec (fixup_symbol_section (sym, objfile),
add_defn_to_vec (fixup_symbol_section (sym, objfile), block);
block); break;
break; }
} }
} }
} }
}
} }
if (! found_sym && arg_sym != NULL) if (! found_sym && arg_sym != NULL)
@ -4219,53 +4222,57 @@ ada_add_block_symbols (block, name, namespace, objfile, wild)
else else
i = 0; i = 0;
for (; i < BLOCK_NSYMS (block); i += 1) 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); {
struct symbol *sym = BLOCK_SYM (block, i);
if (SYMBOL_NAMESPACE (sym) == namespace) if (SYMBOL_NAMESPACE (sym) == namespace)
{ {
int cmp; int cmp;
cmp = (int) '_' - (int) SYMBOL_NAME (sym)[0]; cmp = (int) '_' - (int) SYMBOL_NAME (sym)[0];
if (cmp == 0) if (cmp == 0)
{ {
cmp = strncmp ("_ada_", SYMBOL_NAME (sym), 5); cmp = strncmp ("_ada_", SYMBOL_NAME (sym), 5);
if (cmp == 0) if (cmp == 0)
cmp = strncmp (name, SYMBOL_NAME (sym) + 5, name_len); cmp = strncmp (name, SYMBOL_NAME (sym) + 5, name_len);
} }
if (cmp < 0) if (cmp < 0)
{ {
if (is_sorted) if (is_sorted)
break; {
} i = BLOCK_BUCKETS (block);
else if (cmp == 0 break;
&& is_name_suffix (SYMBOL_NAME (sym) + name_len + 5)) }
{ }
switch (SYMBOL_CLASS (sym)) else if (cmp == 0
{ && is_name_suffix (SYMBOL_NAME (sym) + name_len + 5))
case LOC_ARG: {
case LOC_LOCAL_ARG: switch (SYMBOL_CLASS (sym))
case LOC_REF_ARG: {
case LOC_REGPARM: case LOC_ARG:
case LOC_REGPARM_ADDR: case LOC_LOCAL_ARG:
case LOC_BASEREG_ARG: case LOC_REF_ARG:
arg_sym = sym; case LOC_REGPARM:
break; case LOC_REGPARM_ADDR:
case LOC_UNRESOLVED: case LOC_BASEREG_ARG:
break; arg_sym = sym;
default: break;
found_sym = 1; case LOC_UNRESOLVED:
fill_in_ada_prototype (sym); break;
add_defn_to_vec (fixup_symbol_section (sym, objfile), default:
block); found_sym = 1;
break; 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. /* NOTE: This really shouldn't be needed for _ada_ symbols.
They aren't parameters, right? */ They aren't parameters, right? */
if (! found_sym && arg_sym != NULL) if (! found_sym && arg_sym != NULL)
@ -4292,6 +4299,7 @@ fill_in_ada_prototype (func)
struct type* ftype; struct type* ftype;
struct type* rtype; struct type* rtype;
size_t max_fields; size_t max_fields;
struct symbol *sym;
if (func == NULL if (func == NULL
|| TYPE_CODE (SYMBOL_TYPE (func)) != TYPE_CODE_FUNC || TYPE_CODE (SYMBOL_TYPE (func)) != TYPE_CODE_FUNC
@ -4308,16 +4316,13 @@ fill_in_ada_prototype (func)
SYMBOL_TYPE (func) = ftype; SYMBOL_TYPE (func) = ftype;
b = SYMBOL_BLOCK_VALUE (func); b = SYMBOL_BLOCK_VALUE (func);
nsyms = BLOCK_NSYMS (b);
nargs = 0; nargs = 0;
max_fields = 8; max_fields = 8;
TYPE_FIELDS (ftype) = TYPE_FIELDS (ftype) =
(struct field*) xmalloc (sizeof (struct field) * max_fields); (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); GROW_VECT (TYPE_FIELDS (ftype), max_fields, nargs+1);
switch (SYMBOL_CLASS (sym)) switch (SYMBOL_CLASS (sym))
@ -4903,6 +4908,8 @@ debug_print_block (b)
struct block* b; struct block* b;
{ {
int i; int i;
struct symbol *i;
fprintf (stderr, "Block: %p; [0x%lx, 0x%lx]", fprintf (stderr, "Block: %p; [0x%lx, 0x%lx]",
b, BLOCK_START(b), BLOCK_END(b)); b, BLOCK_START(b), BLOCK_END(b));
if (BLOCK_FUNCTION(b) != NULL) if (BLOCK_FUNCTION(b) != NULL)
@ -4910,11 +4917,11 @@ debug_print_block (b)
fprintf (stderr, "\n"); fprintf (stderr, "\n");
fprintf (stderr, "\t Superblock: %p\n", BLOCK_SUPERBLOCK(b)); fprintf (stderr, "\t Superblock: %p\n", BLOCK_SUPERBLOCK(b));
fprintf (stderr, "\t Symbols:"); 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) if (i > 0 && i % 4 == 0)
fprintf (stderr, "\n\t\t "); fprintf (stderr, "\n\t\t ");
fprintf (stderr, " %s", SYMBOL_NAME (BLOCK_SYM (b, i))); fprintf (stderr, " %s", SYMBOL_NAME (sym));
} }
fprintf (stderr, "\n"); fprintf (stderr, "\n");
} }

View file

@ -40,6 +40,7 @@
#include "bcache.h" #include "bcache.h"
#include "filenames.h" /* For DOSish file names */ #include "filenames.h" /* For DOSish file names */
#include "macrotab.h" #include "macrotab.h"
#include "demangle.h" /* Needed by SYMBOL_INIT_DEMANGLED_NAME. */
/* Ask buildsym.h to define the vars it normally declares `extern'. */ /* Ask buildsym.h to define the vars it normally declares `extern'. */
#define EXTERN #define EXTERN
/**/ /**/
@ -243,17 +244,49 @@ finish_block (struct symbol *symbol, struct pending **listhead,
/* EMPTY */ ; /* EMPTY */ ;
} }
block = (struct block *) obstack_alloc (&objfile->symbol_obstack,
(sizeof (struct block) + ((i - 1) * sizeof (struct symbol *))));
/* Copy the symbols into the block. */ /* Copy the symbols into the block. */
BLOCK_NSYMS (block) = i; if (symbol)
for (next = *listhead; next; next = next->next)
{ {
for (j = next->nsyms - 1; j >= 0; j--) 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
{
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_SYM (block, --i) = next->symbol[j]; BLOCK_BUCKET (block, j) = 0;
}
BLOCK_BUCKETS (block) = htab_size;
for (next = *listhead; next; next = next->next)
{
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); struct type *ftype = SYMBOL_TYPE (symbol);
SYMBOL_BLOCK_VALUE (symbol) = block; SYMBOL_BLOCK_VALUE (symbol) = block;
BLOCK_FUNCTION (block) = symbol; BLOCK_FUNCTION (block) = symbol;
BLOCK_HASHTABLE (block) = 0;
if (TYPE_NFIELDS (ftype) <= 0) if (TYPE_NFIELDS (ftype) <= 0)
{ {
@ -352,6 +386,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
else else
{ {
BLOCK_FUNCTION (block) = NULL; BLOCK_FUNCTION (block) = NULL;
BLOCK_HASHTABLE (block) = 1;
} }
/* Now "free" the links of the list, and empty the list. */ /* Now "free" the links of the list, and empty the list. */

View file

@ -1409,13 +1409,12 @@ patch_opaque_types (struct symtab *s)
/* Go through the per-file symbols only */ /* Go through the per-file symbols only */
b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); 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. /* Find completed typedefs to use to fix opaque ones.
Remove syms from the chain when their types are stored, Remove syms from the chain when their types are stored,
but search the whole chain, as there may be several syms but search the whole chain, as there may be several syms
from different files with the same name. */ from different files with the same name. */
real_sym = BLOCK_SYM (b, i);
if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF && if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF &&
SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE && SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE &&
TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR && TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&

View file

@ -1396,6 +1396,7 @@ process_dst_block (struct objfile *objfile, dst_rec_ptr_t entry)
symnum++; symnum++;
} }
BLOCK_NSYMS (block) = total_symbols; BLOCK_NSYMS (block) = total_symbols;
BLOCK_HASHTABLE (block) = 0;
BLOCK_START (block) = address; BLOCK_START (block) = address;
BLOCK_END (block) = address + size; BLOCK_END (block) = address + size;
BLOCK_SUPERBLOCK (block) = 0; BLOCK_SUPERBLOCK (block) = 0;
@ -1480,6 +1481,7 @@ read_dst_symtab (struct objfile *objfile)
(total_globals - 1) * (total_globals - 1) *
sizeof (struct symbol *)); sizeof (struct symbol *));
BLOCK_NSYMS (global_block) = total_globals; BLOCK_NSYMS (global_block) = total_globals;
BLOCK_HASHTABLE (global_block) = 0;
for (symnum = 0; symnum < total_globals; symnum++) for (symnum = 0; symnum < total_globals; symnum++)
{ {
nextsym = dst_global_symbols->next; nextsym = dst_global_symbols->next;

View file

@ -106,6 +106,7 @@ get_java_class_symtab (void)
bl = (struct block *) bl = (struct block *)
obstack_alloc (&objfile->symbol_obstack, sizeof (struct block)); obstack_alloc (&objfile->symbol_obstack, sizeof (struct block));
BLOCK_NSYMS (bl) = 0; BLOCK_NSYMS (bl) = 0;
BLOCK_HASHTABLE (bl) = 0;
BLOCK_START (bl) = 0; BLOCK_START (bl) = 0;
BLOCK_END (bl) = 0; BLOCK_END (bl) = 0;
BLOCK_FUNCTION (bl) = NULL; BLOCK_FUNCTION (bl) = NULL;

View file

@ -52,6 +52,7 @@
#include "stabsread.h" #include "stabsread.h"
#include "complaints.h" #include "complaints.h"
#include "demangle.h" #include "demangle.h"
#include "gdb_assert.h"
/* These are needed if the tm.h file does not contain the necessary /* These are needed if the tm.h file does not contain the necessary
mips specific definitions. */ mips specific definitions. */
@ -4727,6 +4728,11 @@ shrink_block (struct block *b, struct symtab *s)
+ ((BLOCK_NSYMS (b) - 1) + ((BLOCK_NSYMS (b) - 1)
* sizeof (struct symbol *)))); * 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 /* Should chase pointers to old one. Fortunately, that`s just
the block`s function and inferior blocks */ the block`s function and inferior blocks */
if (BLOCK_FUNCTION (new) && SYMBOL_BLOCK_VALUE (BLOCK_FUNCTION (new)) == b) if (BLOCK_FUNCTION (new) && SYMBOL_BLOCK_VALUE (BLOCK_FUNCTION (new)) == b)

View file

@ -91,7 +91,7 @@ msymbol_hash_iw (const char *string)
++string; ++string;
} }
} }
return hash % MINIMAL_SYMBOL_HASH_SIZE; return hash;
} }
/* Compute a hash code for a string. */ /* Compute a hash code for a string. */
@ -102,7 +102,7 @@ msymbol_hash (const char *string)
unsigned int hash = 0; unsigned int hash = 0;
for (; *string; ++string) for (; *string; ++string)
hash = hash * 67 + *string - 113; 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. */ /* 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) 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]; sym->hash_next = table[hash];
table[hash] = sym; table[hash] = sym;
} }
@ -126,7 +126,7 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
{ {
if (sym->demangled_hash_next == NULL) 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]; sym->demangled_hash_next = table[hash];
table[hash] = sym; 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 *found_file_symbol = NULL;
struct minimal_symbol *trampoline_symbol = NULL; struct minimal_symbol *trampoline_symbol = NULL;
unsigned int hash = msymbol_hash (name); unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
unsigned int dem_hash = msymbol_hash_iw (name); unsigned int dem_hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING #ifdef SOFUN_ADDRESS_MAYBE_MISSING
if (sfile != NULL) if (sfile != NULL)

View file

@ -40,6 +40,7 @@
#include "objfiles.h" /* ditto */ #include "objfiles.h" /* ditto */
#include "completer.h" /* for completion functions */ #include "completer.h" /* for completion functions */
#include "ui-out.h" #include "ui-out.h"
#include "gdb_assert.h"
extern int asm_demangle; /* Whether to demangle syms in asm printouts */ extern int asm_demangle; /* Whether to demangle syms in asm printouts */
extern int addressprint; /* Whether to print hex addresses in HLL " */ 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) if (func)
{ {
b = SYMBOL_BLOCK_VALUE (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) ALL_BLOCK_SYMBOLS (b, i, sym)
{ {
QUIT; QUIT;

View file

@ -86,11 +86,17 @@ static void
free_symtab_block (struct objfile *objfile, struct block *b) free_symtab_block (struct objfile *objfile, struct block *b)
{ {
register int i, n; register int i, n;
n = BLOCK_NSYMS (b); struct symbol *sym, *next_sym;
n = BLOCK_BUCKETS (b);
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
xmfree (objfile->md, SYMBOL_NAME (BLOCK_SYM (b, i))); for (sym = BLOCK_BUCKET (b, i); sym; sym = next_sym)
xmfree (objfile->md, (PTR) BLOCK_SYM (b, i)); {
next_sym = sym->hash_next;
xmfree (objfile->md, SYMBOL_NAME (sym));
xmfree (objfile->md, (PTR) sym);
}
} }
xmfree (objfile->md, (PTR) b); xmfree (objfile->md, (PTR) b);
} }
@ -457,8 +463,14 @@ dump_symtab (struct objfile *objfile, struct symtab *symtab,
fprintf_filtered (outfile, " under "); fprintf_filtered (outfile, " under ");
gdb_print_host_address (BLOCK_SUPERBLOCK (b), outfile); gdb_print_host_address (BLOCK_SUPERBLOCK (b), outfile);
} }
blen = BLOCK_NSYMS (b); /* drow/2002-07-10: We could save the total symbols count
fprintf_filtered (outfile, ", %d syms in ", blen); 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); print_address_numeric (BLOCK_START (b), 1, outfile);
fprintf_filtered (outfile, ".."); fprintf_filtered (outfile, "..");
print_address_numeric (BLOCK_END (b), 1, 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)) if (BLOCK_GCC_COMPILED (b))
fprintf_filtered (outfile, ", compiled with gcc%d", BLOCK_GCC_COMPILED (b)); fprintf_filtered (outfile, ", compiled with gcc%d", BLOCK_GCC_COMPILED (b));
fprintf_filtered (outfile, "\n"); fprintf_filtered (outfile, "\n");
/* Now print each symbol in this block. */ /* Now print each symbol in this block (in no particular order, if
/* FIXMED: Sort? */ we're using a hashtable). */
ALL_BLOCK_SYMBOLS (b, j, sym) ALL_BLOCK_SYMBOLS (b, j, sym)
{ {
struct print_symbol_args s; struct print_symbol_args s;

View file

@ -1328,6 +1328,22 @@ lookup_block_symbol (register const struct block *block, const char *name,
register struct symbol *sym_found = NULL; register struct symbol *sym_found = NULL;
register int do_linear_search = 1; 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 the blocks's symbols were sorted, start with a binary search. */
if (BLOCK_SHOULD_SORT (block)) if (BLOCK_SHOULD_SORT (block))
@ -1582,14 +1598,15 @@ find_pc_sect_symtab (CORE_ADDR pc, asection *section)
if (section != 0) if (section != 0)
{ {
int i; 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); fixup_symbol_section (sym, objfile);
if (section == SYMBOL_BFD_SECTION (b->sym[i])) if (section == SYMBOL_BFD_SECTION (sym))
break; break;
} }
if (i >= b->nsyms) if ((i >= BLOCK_BUCKETS (b)) && (sym == NULL))
continue; /* no symbol in this symtab matches section */ continue; /* no symbol in this symtab matches section */
} }
distance = BLOCK_END (b) - BLOCK_START (b); distance = BLOCK_END (b) - BLOCK_START (b);
@ -1661,10 +1678,8 @@ find_addr_symbol (CORE_ADDR addr, struct symtab **symtabp, CORE_ADDR *symaddrp)
{ {
QUIT; QUIT;
block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), blocknum); block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), blocknum);
top = BLOCK_NSYMS (block); ALL_BLOCK_SYMBOLS (block, bot, sym)
for (bot = 0; bot < top; bot++)
{ {
sym = BLOCK_SYM (block, bot);
switch (SYMBOL_CLASS (sym)) switch (SYMBOL_CLASS (sym))
{ {
case LOC_STATIC: case LOC_STATIC:
@ -2795,10 +2810,9 @@ search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
struct symbol_search *prevtail = tail; struct symbol_search *prevtail = tail;
int nfound = 0; int nfound = 0;
b = BLOCKVECTOR_BLOCK (bv, i); b = BLOCKVECTOR_BLOCK (bv, i);
for (j = 0; j < BLOCK_NSYMS (b); j++) ALL_BLOCK_SYMBOLS (b, j, sym)
{ {
QUIT; QUIT;
sym = BLOCK_SYM (b, j);
if (file_matches (s->filename, files, nfiles) if (file_matches (s->filename, files, nfiles)
&& ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym)) && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym))
&& ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (sym) != LOC_TYPEDEF && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (sym) != LOC_TYPEDEF

View file

@ -386,6 +386,25 @@ struct block
unsigned char gcc_compile_flag; 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. */ /* Number of local symbols. */
int nsyms; int nsyms;
@ -398,30 +417,38 @@ struct block
#define BLOCK_START(bl) (bl)->startaddr #define BLOCK_START(bl) (bl)->startaddr
#define BLOCK_END(bl) (bl)->endaddr #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_FUNCTION(bl) (bl)->function
#define BLOCK_SUPERBLOCK(bl) (bl)->superblock #define BLOCK_SUPERBLOCK(bl) (bl)->superblock
#define BLOCK_GCC_COMPILED(bl) (bl)->gcc_compile_flag #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. /* For blocks without a hashtable (BLOCK_HASHTABLE (bl) == 0) only. */
i counts which symbol we are looking at, and sym points to the current #define BLOCK_NSYMS(bl) (bl)->nsyms
symbol. #define BLOCK_SYM(bl, n) (bl)->sym[n]
The contortion at the end is to avoid reading past the last valid
BLOCK_SYM. */ /* For blocks with a hashtable, but these are valid for non-hashed blocks as
#define ALL_BLOCK_SYMBOLS(bl, i, sym) \ well - each symbol will appear to be one bucket by itself. */
for ((i) = 0, (sym) = BLOCK_SYM ((bl), (i)); \ #define BLOCK_BUCKETS(bl) (bl)->nsyms
(i) < BLOCK_NSYMS ((bl)); \ #define BLOCK_BUCKET(bl, n) (bl)->sym[n]
++(i), (sym) = ((i) < BLOCK_NSYMS ((bl))) \
? BLOCK_SYM ((bl), (i)) \ /* Macro used to set the size of a hashtable for N symbols. */
: NULL) #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. /* Nonzero if symbols of block BL should be sorted alphabetically.
Don't sort a block which corresponds to a function. If we did the 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 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)
/* Represent one symbol name; a variable, constant, function or typedef. */ /* 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 /* List of ranges where this symbol is active. This is only
used by alias symbols at the current time. */ used by alias symbols at the current time. */
struct range_list *ranges; struct range_list *ranges;
struct symbol *hash_next;
}; };