C++ improvements
authorDaniel Berlin <dberlin@dberlin.org>
Mon, 5 Jun 2000 20:49:53 +0000 (20:49 +0000)
committerDaniel Berlin <dberlin@dberlin.org>
Mon, 5 Jun 2000 20:49:53 +0000 (20:49 +0000)
gdb/ChangeLog
gdb/bcache.c
gdb/bcache.h
gdb/buildsym.c
gdb/c-exp.y
gdb/dwarf2read.c
gdb/symtab.c
gdb/symtab.h

index d909d04..6b51c40 100644 (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):
index 96c01ba..fcff55e 100644 (file)
 #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.  */
 
index 4735af7..5355e74 100644 (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 */
index dff9293..70105be 100644 (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;
 }
 \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
 
index a52416f..d4291f7 100644 (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];
     }
index 73ccd06..b6a340f 100644 (file)
 #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);
index 41c23aa..5f0e84a 100644 (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
index 5fe5bc3..7fb78db 100644 (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).  */