+2000-06-05 Daniel Berlin <dan@cgsoftware.com>
+
+ * c-exp.y (yylex): template handling fixes.
+
+2000-06-03 Daniel Berlin <dan@cgsoftware.com>
+
+ * symtab.h (VTBL_PREFIX_P): Add newer g++ vtbl prefix to prefix list.
+
+ * symtab.c (lookup_partial_symbol): Change to stop forcing linear searches
+ on C++ when we fail the binary search, by doing the binary search right.
+
+2000-05-30 Daniel Berlin <dan@cgsoftware.com>
+
+ * buildsym.c (hashname): Change to use hash function from bcache.c/.h
+
+ * bcache.c (hash): Change to newer hash function.
+
+ * bcache.h (hash): Prototype for hash function
+
+ * dwarf2read.c (TYPE_HASH_SIZE): New define for controlling size
+ of type hash.
+ (dwarf2_cached_types): New variable that is the cached types.
+ (tag_type_to_type): Do the actual caching of types here.
+
2000-06-05 Mark Kettenis <kettenis@gnu.org>
* acconfig.h, configure.in, i386bsd.c (HAVE_STRUCT_REG_R_FS):
#include "bcache.h"
#include "gdb_string.h" /* For memcpy declaration */
-
+/* The old hash function was stolen from SDBM. This is what DB 3.0 uses now,
+ * and is better than the old one.
+ */
\f
-/* The hash function. */
-
unsigned long
-hash (void *addr, int length)
+hash(void *addr, int length)
{
- /* If it's a short string, hash on every character. Otherwise, sample
- characters from throughout the string. */
- if (length <= 64)
- {
- char *byte = addr;
- unsigned long h = 0;
- int i;
-
- for (i = 0; i < length; i++)
- h = h * 65793 ^ (h >> (sizeof (h) * 8 - 6)) ^ byte[i];
-
- return h;
- }
- else
- {
- char *byte = addr;
- int n, i;
- unsigned long h = 0;
-
- for (n = i = 0; n < 64; n++)
- {
- h = h * 65793 + (h >> (sizeof (h) * 8 - 6)) + byte[i];
- i = h % length;
- }
-
- return h;
- }
+ const unsigned char *k, *e;
+ unsigned long h;
+
+ k = (const unsigned char *)addr;
+ e = k+length;
+ for (h=0; k< e;++k)
+ {
+ h *=16777619;
+ h ^= *k;
+ }
+ return (h);
}
-
\f
/* Growing the bcache's hash table. */
kind of data BCACHE holds. Statistics are printed using
`printf_filtered' and its ilk. */
extern void print_bcache_statistics (struct bcache *bcache, char *type);
-
+/* The hash function */
+extern unsigned long hash(void *addr, int length);
#endif /* BCACHE_H */
#include "gdb_string.h"
#include "expression.h" /* For "enum exp_opcode" used by... */
#include "language.h" /* For "longest_local_hex_string_custom" */
-
+#include "bcache.h"
/* Ask buildsym.h to define the vars it normally declares `extern'. */
#define EXTERN
/**/
return new;
}
\f
+
/* Compute a small integer hash code for the given name. */
int
hashname (char *name)
{
- register char *p = name;
- register int total = p[0];
- register int c;
-
- c = p[1];
- total += c << 2;
- if (c)
- {
- c = p[2];
- total += c << 4;
- if (c)
- {
- total += p[3] << 6;
- }
- }
-
- /* Ensure result is positive. */
- if (total < 0)
- {
- total += (1000 << 6);
- }
- return (total % HASHSIZE);
+ return (hash(name,strlen(name)) % HASHSIZE);
}
\f
if (c == '<')
{
- if (hp_som_som_object_present)
- {
/* Scan ahead to get rest of the template specification. Note
that we look ahead only when the '<' adjoins non-whitespace
characters; for comparison expressions, e.g. "a < b > c",
if (p)
namelen = p - tokstart;
break;
- }
- else
- {
- int i = namelen;
- int nesting_level = 1;
- while (tokstart[++i])
- {
- if (tokstart[i] == '<')
- nesting_level++;
- else if (tokstart[i] == '>')
- {
- if (--nesting_level == 0)
- break;
- }
- }
- if (tokstart[i] == '>')
- namelen = i;
- else
- break;
- }
}
c = tokstart[++namelen];
}
#include "buildsym.h"
#include "demangle.h"
#include "expression.h"
+
#include "language.h"
#include "complaints.h"
-
+#include "bcache.h"
#include <fcntl.h>
#include "gdb_string.h"
#include <sys/types.h>
-/* .debug_info header for a compilation unit
+/* .debug_info header for a compilation unit
Because of alignment constraints, this structure has padding and cannot
be mapped directly onto the beginning of the .debug_info section. */
typedef struct comp_unit_header
static struct die_info *die_ref_table[REF_HASH_SIZE];
+#ifndef TYPE_HASH_SIZE
+#define TYPE_HASH_SIZE 4096
+#endif
+static struct type *dwarf2_cached_types[TYPE_HASH_SIZE];
+
/* Obstack for allocating temporary storage used during symbol reading. */
static struct obstack dwarf2_tmp_obstack;
static int frame_base_reg;
static CORE_ADDR frame_base_offset;
-/* This value is added to each symbol value. FIXME: Generalize to
+/* This value is added to each symbol value. FIXME: Generalize to
the section_offsets structure used by dbxread (once this is done,
pass the appropriate section number to end_symtab). */
static CORE_ADDR baseaddr; /* Add to each symbol value */
DW_AT_name: /srcdir/list0.c
DW_AT_comp_dir: /compdir
- files.files[0].name: list0.h
+ files.files[0].name: list0.h
files.files[0].dir: /srcdir
- files.files[1].name: list0.c
+ files.files[1].name: list0.c
files.files[1].dir: /srcdir
The line number information for list0.c has to end up in a single
}
else
{
- read_type_die (die, objfile);
+ struct attribute *attr;
+ attr = dwarf_attr (die, DW_AT_name);
+ if (attr && DW_STRING (attr))
+ {
+ char *attrname=DW_STRING (attr);
+ unsigned long hashval=hash(attrname, strlen(attrname)) % TYPE_HASH_SIZE;
+
+ if (dwarf2_cached_types[hashval] != NULL)
+ {
+ const char *nameoftype;
+ nameoftype = TYPE_NAME(dwarf2_cached_types[hashval]) == NULL ? TYPE_TAG_NAME(dwarf2_cached_types[hashval]) : TYPE_NAME(dwarf2_cached_types[hashval]);
+ if (strcmp(attrname, nameoftype) == 0)
+ {
+ die->type=dwarf2_cached_types[hashval];
+ }
+ else
+ {
+ read_type_die (die, objfile);
+ dwarf2_cached_types[hashval] = die->type;
+ }
+ }
+ else
+ {
+ read_type_die (die, objfile);
+ dwarf2_cached_types[hashval] = die->type;
+ }
+ }
+ else
+ {
+ read_type_die (die, objfile);
+ }
+
if (!die->type)
{
dump_die (die);
*symtab = NULL;
return 0;
}
-
+
/* Look, in partial_symtab PST, for symbol NAME. Check the global
symbols if GLOBAL, the static symbols if not */
int global;
namespace_enum namespace;
{
+ struct partial_symbol *temp;
struct partial_symbol **start, **psym;
struct partial_symbol **top, **bottom, **center;
int length = (global ? pst->n_global_syms : pst->n_static_syms);
int do_linear_search = 1;
-
+
if (length == 0)
{
return (NULL);
}
-
start = (global ?
pst->objfile->global_psymbols.list + pst->globals_offset :
pst->objfile->static_psymbols.list + pst->statics_offset);
-
+
if (global) /* This means we can use a binary search. */
{
do_linear_search = 0;
if (!(center < top))
abort ();
if (!do_linear_search
- && (SYMBOL_LANGUAGE (*center) == language_cplus
- || SYMBOL_LANGUAGE (*center) == language_java
- ))
+ && (SYMBOL_LANGUAGE (*center) == language_java))
{
do_linear_search = 1;
}
}
if (!(top == bottom))
abort ();
- while (STREQ (SYMBOL_NAME (*top), name))
+
+ /* djb - 2000-06-03 - Use SYMBOL_MATCHES_NAME, not a strcmp, so
+ we don't have to force a linear search on C++. Probably holds true
+ for JAVA as well, no way to check.*/
+ while (SYMBOL_MATCHES_NAME (*top,name))
{
if (SYMBOL_NAMESPACE (*top) == namespace)
{
- return (*top);
+ return (*top);
}
top++;
}
we should also do a linear search. */
if (do_linear_search)
- {
+ {
for (psym = start; psym < start + length; psym++)
{
if (namespace == SYMBOL_NAMESPACE (*psym))
symtab_symbol_info (regexp, FUNCTIONS_NAMESPACE, from_tty);
}
+
static void
types_info (regexp, from_tty)
char *regexp;
add_info ("functions", functions_info,
"All function names, or those matching REGEXP.");
+
/* FIXME: This command has at least the following problems:
1. It prints builtin types (in a very strange and confusing fashion).
2. It doesn't print right, e.g. with
style, using thunks (where '$' is really CPLUS_MARKER). */
#define VTBL_PREFIX_P(NAME) \
- ((NAME)[0] == '_' \
+ (((NAME)[0] == '_' \
&& (((NAME)[1] == 'V' && (NAME)[2] == 'T') \
|| ((NAME)[1] == 'v' && (NAME)[2] == 't')) \
- && is_cplus_marker ((NAME)[3]))
+ && is_cplus_marker ((NAME)[3])) || ((NAME)[0]=='_' && (NAME)[1]=='_' \
+ && (NAME)[2]=='v' && (NAME)[3]=='t' && (NAME)[4]=='_'))
/* Macro that yields non-zero value iff NAME is the prefix for C++ destructor
names. Note that this macro is g++ specific (FIXME). */