C++ improvements

This commit is contained in:
Daniel Berlin 2000-06-05 20:49:53 +00:00
parent e6d71bf34e
commit 357e46e7c9
8 changed files with 104 additions and 96 deletions

View file

@ -1,3 +1,27 @@
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):

View file

@ -28,42 +28,25 @@
#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.
*/
/* 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);
}
/* Growing the bcache's hash table. */

View file

@ -125,5 +125,6 @@ extern void free_bcache (struct bcache *bcache);
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 */

View file

@ -36,7 +36,7 @@
#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
/**/
@ -1055,33 +1055,13 @@ push_context (int desc, CORE_ADDR valu)
return new;
}
/* 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);
}

View file

@ -1433,8 +1433,6 @@ yylex ()
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",
@ -1444,26 +1442,6 @@ yylex ()
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];
}

View file

@ -35,14 +35,15 @@
#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
@ -267,6 +268,11 @@ static struct abbrev_info *dwarf2_abbrevs[ABBREV_HASH_SIZE];
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;
@ -333,7 +339,7 @@ static int islocal; /* Variable is at the returned offset
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 */
@ -3960,9 +3966,9 @@ done:
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
@ -4449,7 +4455,38 @@ tag_type_to_type (die, objfile)
}
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);

View file

@ -954,7 +954,7 @@ lookup_symbol (name, block, namespace, is_a_field_of_this, symtab)
*symtab = NULL;
return 0;
}
/* Look, in partial_symtab PST, for symbol NAME. Check the global
symbols if GLOBAL, the static symbols if not */
@ -965,20 +965,20 @@ lookup_partial_symbol (pst, name, global, namespace)
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;
@ -996,9 +996,7 @@ lookup_partial_symbol (pst, name, global, namespace)
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;
}
@ -1013,11 +1011,15 @@ lookup_partial_symbol (pst, name, global, namespace)
}
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++;
}
@ -1027,7 +1029,7 @@ lookup_partial_symbol (pst, name, global, namespace)
we should also do a linear search. */
if (do_linear_search)
{
{
for (psym = start; psym < start + length; psym++)
{
if (namespace == SYMBOL_NAMESPACE (*psym))
@ -4018,6 +4020,7 @@ functions_info (regexp, from_tty)
symtab_symbol_info (regexp, FUNCTIONS_NAMESPACE, from_tty);
}
static void
types_info (regexp, from_tty)
char *regexp;
@ -4664,6 +4667,7 @@ _initialize_symtab ()
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

View file

@ -1059,10 +1059,11 @@ struct partial_symtab
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). */