From 357e46e7c9f18a0603aa9a6de440bedb147e57f8 Mon Sep 17 00:00:00 2001 From: Daniel Berlin Date: Mon, 5 Jun 2000 20:49:53 +0000 Subject: [PATCH] C++ improvements --- gdb/ChangeLog | 24 ++++++++++++++++++++++++ gdb/bcache.c | 47 +++++++++++++++------------------------------- gdb/bcache.h | 3 ++- gdb/buildsym.c | 26 +++---------------------- gdb/c-exp.y | 22 ---------------------- gdb/dwarf2read.c | 49 ++++++++++++++++++++++++++++++++++++++++++------ gdb/symtab.c | 24 ++++++++++++++---------- gdb/symtab.h | 5 +++-- 8 files changed, 104 insertions(+), 96 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d909d040755..6b51c40aa62 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,27 @@ +2000-06-05 Daniel Berlin + + * c-exp.y (yylex): template handling fixes. + +2000-06-03 Daniel Berlin + + * 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 + + * 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 * acconfig.h, configure.in, i386bsd.c (HAVE_STRUCT_REG_R_FS): diff --git a/gdb/bcache.c b/gdb/bcache.c index 96c01ba4655..fcff55e5ac9 100644 --- a/gdb/bcache.c +++ b/gdb/bcache.c @@ -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. */ diff --git a/gdb/bcache.h b/gdb/bcache.h index 4735af71cd3..5355e7481c2 100644 --- a/gdb/bcache.h +++ b/gdb/bcache.h @@ -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 */ diff --git a/gdb/buildsym.c b/gdb/buildsym.c index dff92936cfd..70105be0157 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -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); } diff --git a/gdb/c-exp.y b/gdb/c-exp.y index a52416f48f9..d4291f7b979 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -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]; } diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 73ccd0644b6..b6a340f7f4a 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -35,14 +35,15 @@ #include "buildsym.h" #include "demangle.h" #include "expression.h" + #include "language.h" #include "complaints.h" - +#include "bcache.h" #include #include "gdb_string.h" #include -/* .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); diff --git a/gdb/symtab.c b/gdb/symtab.c index 41c23aa6b14..5f0e84aeefe 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -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 diff --git a/gdb/symtab.h b/gdb/symtab.h index 5fe5bc3d17c..7fb78db3ea7 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -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). */ -- 2.30.2