This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: Demangle partial symbols and save memory too


On Tue, Jan 28, 2003 at 06:52:02PM -0500, Jim Blandy wrote:
> 
> Hey, this is a great idea!
> 
> Complaints:
> 
> > +
> > +    /* Hash table for mapping symbol names to demangled names.  */
> > +    struct htab *demangled_names_hash;
> 
> Dude, you have *got* to document this in more detail if you're going
> to use such an unusual representation for the values.  "Two null-
> terminated, concatenated strings, the second of which is empty if the
> name is not mangled" is simply not what people are going to guess.

I documented it down where it's used, but I've got no problem with
putting it there too.  That's a good idea.

> I'd really rather see the elements of the hash table be structs, but
> that'd add an extra eight bytes, even for names with no manglings.
> How much of the savings would that eat?
> 
> (It feels odd to be using weirdo representations here without having a
> sense of whether they're really more important elsewhere.  I'm looking
> forward to your further investigations.)

Too much.  In my test case, there were about 200,000 entries in these
hash tables across all objfiles.  That'd eat 1.6 MB; a little less,
since that would allow me to drop the unintuitive second trailing zero
when names don't demangle, but that's a lot of memory.  About 3%, I
think, after I'm done plugging leaks.

I can probably shave off at least that much memory somewhere else, but
I think it would qualify as wasteful.

[Oh, it occurs to me that I can actually cut the waste down to 3-4
bytes per name on 32-bit hosts by putting the structs directly in the
hash table.  Change the 3% to 1% above and repeat the argument, I think
it still holds water.]

> Maybe I'm misreading what you've done to symbol_init_demangled_name,
> but it doesn't look right.  In theory, different languages could have
> radically different contents in their symbols' language_specific
> union.  It looks to me as if you just assign to
> symbol->language_specific.cplus_specific.demangled_name no matter what
> the language is.

Yes, that's true.  It's functionally equivalent to what the function
did before, but it's true.  My inclination, as I mentioned on gdb@ a
couple of days ago, is to move demangled_name out of the
language_specific structure, thus rendering it empty for all languages;
and either leave it empty if we think it will be useful, or just kill
it.

That's for another patch, though, so I've just re-added the language
checks.

> The semantics of symbol_find_demangled_name are also a bit odd.  It
> sets the symbol's language, but returns its demangled name, leaving
> the demangled name in the symbol itself untouched.

Yes; that's because I just needed it as a helper for two functions. 
I'd rather kill symbol_init_demangled_name but I'm not brave enough to
tackle hpread right now.

> 
> > +	*(*slot + len + 1) = 0;
> 
> How about (*slot)[len + 1] = '\0'; etc.?

We have a winner.  Sure.

I also fixed up some consts that David pointed out; here's an update.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2003-01-29  Daniel Jacobowitz  <drow@mvista.com>

	* defs.h (streq): Add prototype.
	* utils.c (streq): New function.

	* dwarf2read.c (new_symbol): Use SYMBOL_SET_NAMES instead of
	SYMBOL_NAME and SYMBOL_INIT_DEMANGLED_NAME.
	* mdebugread.c (new_symbol): Likewise.
	* stabsread.c (define_symbol): Likewise.
	* coffread.c (process_coff_symbol): Likewise.
	* dwarfread.c (new_symbol): Likewise.

	* minsyms.c (prim_record_minimal_symbol_and_info): Use
	SYMBOL_SET_NAMES instead of setting SYMBOL_NAME.  Set the language
	here.
	(install_minimal_symbols): Don't set SYMBOL_LANGUAGE or call
	SYMBOL_INIT_DEMANGLED_NAME.
	* objfiles.c: Include "hashtab.h".
	(allocate_objfile): Call htab_set_functions_ex for the
	demangled_names_hash.
	(free_objfile): Call htab_delete for the demangled_names_hash.
	* objfiles.h (struct htab): Add declaration.
	(struct objfile): Add demangled_names_hash.
	* symfile.c: Include "hashtab.h".
	(reread_symbols): Call htab_delete for the demangled_names_hash.
	(add_psymbol_to_list): Use SYMBOL_SET_NAMES instead of putting
	SYMBOL_NAME in the bcache.
	* symtab.c: Include "hashtab.h".  Update comments.
	(create_demangled_names_hash, symbol_set_names): New functions.
	(symbol_find_demangled_name): New function, broken out from
	symbol_init_demangled_names.
	(symbol_init_demangled_names): Use it.
	* symtab.h (SYMBOL_INIT_DEMANGLED_NAME): Add missing parentheses.
	(SYMBOL_SET_NAMES): New macro.
	(symbol_set_names): Add prototype.

Index: coffread.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/coffread.c,v
retrieving revision 1.32
diff -u -p -r1.32 coffread.c
--- coffread.c	17 Dec 2002 00:39:07 -0000	1.32
+++ coffread.c	26 Jan 2003 22:20:09 -0000
@@ -1469,10 +1469,8 @@ process_coff_symbol (register struct cof
   memset (sym, 0, sizeof (struct symbol));
   name = cs->c_name;
   name = EXTERNAL_NAME (name, objfile->obfd);
-  SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
-				    &objfile->symbol_obstack);
   SYMBOL_LANGUAGE (sym) = language_auto;
-  SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+  SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
 
   /* default assumptions */
   SYMBOL_VALUE (sym) = cs->c_value;
Index: defs.h
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/defs.h,v
retrieving revision 1.110
diff -u -p -r1.110 defs.h
--- defs.h	23 Jan 2003 23:03:31 -0000	1.110
+++ defs.h	26 Jan 2003 20:17:13 -0000
@@ -308,6 +308,8 @@ extern void notice_quit (void);
 
 extern int strcmp_iw (const char *, const char *);
 
+extern int streq (const char *, const char *);
+
 extern int subset_compare (char *, char *);
 
 extern char *safe_strerror (int);
Index: dwarf2read.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/dwarf2read.c,v
retrieving revision 1.79
diff -u -p -r1.79 dwarf2read.c
--- dwarf2read.c	18 Jan 2003 15:55:51 -0000	1.79
+++ dwarf2read.c	26 Jan 2003 20:17:13 -0000
@@ -4727,8 +4727,10 @@ new_symbol (struct die_info *die, struct
 					     sizeof (struct symbol));
       OBJSTAT (objfile, n_syms++);
       memset (sym, 0, sizeof (struct symbol));
-      SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
-					&objfile->symbol_obstack);
+
+      /* Cache this symbol's name and the name's demangled form (if any).  */
+      SYMBOL_LANGUAGE (sym) = cu_language;
+      SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
 
       /* Default assumptions.
          Use the passed type or decode it from the die.  */
@@ -4743,15 +4745,6 @@ new_symbol (struct die_info *die, struct
 	{
 	  SYMBOL_LINE (sym) = DW_UNSND (attr);
 	}
-
-      /* If this symbol is from a C++ compilation, then attempt to
-         cache the demangled form for future reference.  This is a
-         typical time versus space tradeoff, that was decided in favor
-         of time because it sped up C++ symbol lookups by a factor of
-         about 20. */
-
-      SYMBOL_LANGUAGE (sym) = cu_language;
-      SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
       switch (die->tag)
 	{
 	case DW_TAG_label:
Index: dwarfread.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/dwarfread.c,v
retrieving revision 1.21
diff -u -p -r1.21 dwarfread.c
--- dwarfread.c	19 Jan 2003 04:06:45 -0000	1.21
+++ dwarfread.c	26 Jan 2003 22:22:05 -0000
@@ -2780,8 +2780,6 @@ new_symbol (struct dieinfo *dip, struct 
 					     sizeof (struct symbol));
       OBJSTAT (objfile, n_syms++);
       memset (sym, 0, sizeof (struct symbol));
-      SYMBOL_NAME (sym) = create_name (dip->at_name,
-				       &objfile->symbol_obstack);
       /* default assumptions */
       SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
       SYMBOL_CLASS (sym) = LOC_STATIC;
@@ -2793,7 +2791,7 @@ new_symbol (struct dieinfo *dip, struct 
          C++ symbol lookups by a factor of about 20. */
 
       SYMBOL_LANGUAGE (sym) = cu_language;
-      SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+      SYMBOL_SET_NAMES (sym, dip->at_name, strlen (dip->at_name), objfile);
       switch (dip->die_tag)
 	{
 	case TAG_label:
Index: mdebugread.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/mdebugread.c,v
retrieving revision 1.39
diff -u -p -r1.39 mdebugread.c
--- mdebugread.c	18 Jan 2003 15:55:52 -0000	1.39
+++ mdebugread.c	26 Jan 2003 20:17:13 -0000
@@ -4779,10 +4779,8 @@ new_symbol (char *name)
 				     sizeof (struct symbol)));
 
   memset (s, 0, sizeof (*s));
-  SYMBOL_NAME (s) = obsavestring (name, strlen (name),
-				  &current_objfile->symbol_obstack);
   SYMBOL_LANGUAGE (s) = psymtab_language;
-  SYMBOL_INIT_DEMANGLED_NAME (s, &current_objfile->symbol_obstack);
+  SYMBOL_SET_NAMES (s, name, strlen (name), current_objfile);
   return s;
 }
 
Index: minsyms.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/minsyms.c,v
retrieving revision 1.23
diff -u -p -r1.23 minsyms.c
--- minsyms.c	8 Jan 2003 18:38:47 -0000	1.23
+++ minsyms.c	26 Jan 2003 20:17:13 -0000
@@ -611,9 +611,10 @@ prim_record_minimal_symbol_and_info (con
       msym_bunch = new;
     }
   msymbol = &msym_bunch->contents[msym_bunch_index];
-  SYMBOL_NAME (msymbol) = obsavestring ((char *) name, strlen (name),
-					&objfile->symbol_obstack);
   SYMBOL_INIT_LANGUAGE_SPECIFIC (msymbol, language_unknown);
+  SYMBOL_LANGUAGE (msymbol) = language_auto;
+  SYMBOL_SET_NAMES (msymbol, (char *)name, strlen (name), objfile);
+
   SYMBOL_VALUE_ADDRESS (msymbol) = address;
   SYMBOL_SECTION (msymbol) = section;
   SYMBOL_BFD_SECTION (msymbol) = bfd_section;
@@ -865,7 +866,6 @@ install_minimal_symbols (struct objfile 
 	  for (bindex = 0; bindex < msym_bunch_index; bindex++, mcount++)
 	    {
 	      msymbols[mcount] = bunch->contents[bindex];
-	      SYMBOL_LANGUAGE (&msymbols[mcount]) = language_auto;
 	      if (SYMBOL_NAME (&msymbols[mcount])[0] == leading_char)
 		{
 		  SYMBOL_NAME (&msymbols[mcount])++;
@@ -925,11 +925,6 @@ install_minimal_symbols (struct objfile 
 	      }
 	  }
       }
-      
-      /* Now walk through all the minimal symbols, selecting the newly added
-         ones and attempting to cache their C++ demangled names. */
-      for (; mcount-- > 0; msymbols++)
-	SYMBOL_INIT_DEMANGLED_NAME (msymbols, &objfile->symbol_obstack);
 
       /* Now build the hash tables; we can't do this incrementally
          at an earlier point since we weren't finished with the obstack
Index: objfiles.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/objfiles.c,v
retrieving revision 1.24
diff -u -p -r1.24 objfiles.c
--- objfiles.c	23 Jan 2003 23:03:31 -0000	1.24
+++ objfiles.c	26 Jan 2003 20:17:13 -0000
@@ -39,6 +39,7 @@
 #include <fcntl.h>
 #include "gdb_obstack.h"
 #include "gdb_string.h"
+#include "hashtab.h"
 
 #include "breakpoint.h"
 
@@ -191,6 +192,11 @@ allocate_objfile (bfd *abfd, int flags)
 	      objfile->md = md;
 	      objfile->mmfd = fd;
 	      /* Update pointers to functions to *our* copies */
+	      if (objfile->demangled_names_hash)
+		htab_set_functions_ex
+		  (objfile->demangled_names_hash, htab_hash_string,
+		   (int (*) (const void *, const void *)) streq, NULL,
+		   objfile->md, xmcalloc, xmfree);
 	      obstack_chunkfun (&objfile->psymbol_cache.cache, xmmalloc);
 	      obstack_freefun (&objfile->psymbol_cache.cache, xmfree);
 	      obstack_chunkfun (&objfile->macro_cache.cache, xmmalloc);
@@ -522,6 +528,8 @@ free_objfile (struct objfile *objfile)
       /* Free the obstacks for non-reusable objfiles */
       bcache_xfree (objfile->psymbol_cache);
       bcache_xfree (objfile->macro_cache);
+      if (objfile->demangled_names_hash)
+	htab_delete (objfile->demangled_names_hash);
       obstack_free (&objfile->psymbol_obstack, 0);
       obstack_free (&objfile->symbol_obstack, 0);
       obstack_free (&objfile->type_obstack, 0);
Index: objfiles.h
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/objfiles.h,v
retrieving revision 1.17
diff -u -p -r1.17 objfiles.h
--- objfiles.h	23 Jan 2003 23:03:31 -0000	1.17
+++ objfiles.h	30 Jan 2003 00:55:47 -0000
@@ -27,6 +27,7 @@
 #include "symfile.h"		/* For struct psymbol_allocation_list */
 
 struct bcache;
+struct htab;
 
 /* This structure maintains information on a per-objfile basis about the
    "entry point" of the objfile, and the scope within which the entry point
@@ -284,6 +285,13 @@ struct objfile
 
     struct bcache *psymbol_cache;	/* Byte cache for partial syms */
     struct bcache *macro_cache;          /* Byte cache for macros */
+
+    /* Hash table for mapping symbol names to demangled names.  Each
+       entry in the hash table is actually two consecutive strings,
+       both null-terminated; the first one is a mangled or linkage
+       name, and the second is the demangled name or just a zero byte
+       if the name doesn't demangle.  */
+    struct htab *demangled_names_hash;
 
     /* Vectors of all partial symbols read in from file.  The actual data
        is stored in the psymbol_obstack. */
Index: stabsread.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/stabsread.c,v
retrieving revision 1.52
diff -u -p -r1.52 stabsread.c
--- stabsread.c	19 Jan 2003 04:06:46 -0000	1.52
+++ stabsread.c	26 Jan 2003 20:17:13 -0000
@@ -1332,23 +1332,13 @@ define_symbol (CORE_ADDR valu, char *str
       if (refnum >= 0)
 	{
 	  if (nlen > 0)
-	    {
-	      SYMBOL_NAME (sym) = (char *)
-		obstack_alloc (&objfile->symbol_obstack, nlen);
-	      strncpy (SYMBOL_NAME (sym), s, nlen);
-	      SYMBOL_NAME (sym)[nlen] = '\0';
-	      SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
-	    }
+	    SYMBOL_SET_NAMES (sym, s, nlen, objfile);
 	  else
 	    /* FIXME! Want SYMBOL_NAME (sym) = 0;
 	       Get error if leave name 0.  So give it something. */
 	    {
 	      nlen = p - string;
-	      SYMBOL_NAME (sym) = (char *)
-		obstack_alloc (&objfile->symbol_obstack, nlen);
-	      strncpy (SYMBOL_NAME (sym), string, nlen);
-	      SYMBOL_NAME (sym)[nlen] = '\0';
-	      SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+	      SYMBOL_SET_NAMES (sym, string, nlen, objfile);
 	    }
 	}
       /* Advance STRING beyond the reference id.  */
@@ -1358,29 +1348,7 @@ define_symbol (CORE_ADDR valu, char *str
     {
     normal:
       SYMBOL_LANGUAGE (sym) = current_subfile->language;
-      SYMBOL_NAME (sym) = (char *)
-	obstack_alloc (&objfile->symbol_obstack, ((p - string) + 1));
-      /* Open-coded memcpy--saves function call time.  */
-      /* FIXME:  Does it really?  Try replacing with simple strcpy and
-         try it on an executable with a large symbol table. */
-      /* FIXME: considering that gcc can open code memcpy anyway, I
-         doubt it.  xoxorich. */
-      {
-	register char *p1 = string;
-	register char *p2 = SYMBOL_NAME (sym);
-	while (p1 != p)
-	  {
-	    *p2++ = *p1++;
-	  }
-	*p2++ = '\0';
-      }
-
-      /* If this symbol is from a C++ compilation, then attempt to cache the
-         demangled form for future reference.  This is a typical time versus
-         space tradeoff, that was decided in favor of time because it sped up
-         C++ symbol lookups by a factor of about 20. */
-
-      SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+      SYMBOL_SET_NAMES (sym, string, p - string, objfile);
     }
   p++;
 
Index: symfile.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/symfile.c,v
retrieving revision 1.82
diff -u -p -r1.82 symfile.c
--- symfile.c	23 Jan 2003 23:17:28 -0000	1.82
+++ symfile.c	26 Jan 2003 21:34:48 -0000
@@ -43,6 +43,7 @@
 #include "gdb_obstack.h"
 #include "completer.h"
 #include "bcache.h"
+#include "hashtab.h"
 #include <readline/readline.h>
 #include "gdb_assert.h"
 
@@ -1979,6 +1980,11 @@ reread_symbols (void)
 	      objfile->psymbol_cache = bcache_xmalloc ();
 	      bcache_xfree (objfile->macro_cache);
 	      objfile->macro_cache = bcache_xmalloc ();
+	      if (objfile->demangled_names_hash != NULL)
+		{
+		  htab_delete (objfile->demangled_names_hash);
+		  objfile->demangled_names_hash = NULL;
+		}
 	      obstack_free (&objfile->psymbol_obstack, 0);
 	      obstack_free (&objfile->symbol_obstack, 0);
 	      obstack_free (&objfile->type_obstack, 0);
@@ -2679,7 +2685,6 @@ add_psymbol_to_list (char *name, int nam
   /* Create local copy of the partial symbol */
   memcpy (buf, name, namelength);
   buf[namelength] = '\0';
-  SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, objfile->psymbol_cache);
   /* val and coreaddr are mutually exclusive, one of them *will* be zero */
   if (val != 0)
     {
@@ -2693,7 +2698,8 @@ add_psymbol_to_list (char *name, int nam
   SYMBOL_LANGUAGE (&psymbol) = language;
   PSYMBOL_NAMESPACE (&psymbol) = namespace;
   PSYMBOL_CLASS (&psymbol) = class;
-  SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language);
+
+  SYMBOL_SET_NAMES (&psymbol, buf, namelength, objfile);
 
   /* Stash the partial symbol away in the cache */
   psym = bcache (&psymbol, sizeof (struct partial_symbol), objfile->psymbol_cache);
@@ -3559,7 +3565,6 @@ simple_overlay_update (struct obj_sectio
     }
 }
 
-
 void
 _initialize_symfile (void)
 {
@@ -3662,5 +3667,4 @@ Usage: set extension-language .foo bar",
         &setlist));
   add_show_from_set (c, &showlist);
   set_cmd_completer (c, filename_completer);
-
 }
Index: symtab.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/symtab.c,v
retrieving revision 1.85
diff -u -p -r1.85 symtab.c
--- symtab.c	13 Jan 2003 21:59:53 -0000	1.85
+++ symtab.c	30 Jan 2003 01:11:55 -0000
@@ -41,6 +41,8 @@
 #include "source.h"
 #include "filenames.h"		/* for FILENAME_CMP */
 
+#include "hashtab.h"
+
 #include "gdb_obstack.h"
 
 #include <sys/types.h>
@@ -425,22 +427,35 @@ symbol_init_language_specific (struct ge
     }
 }
 
-/* Initialize a symbol's mangled name.  */
+/* Functions to initialize a symbol's mangled name.  */
+
+/* Create the hash table used for demangled names.  Each hash entry is
+   a pair of strings; one for the mangled name and one for the demangled
+   name.  The entry is hashed via just the mangled name.  */
+
+static void
+create_demangled_names_hash (struct objfile *objfile)
+{
+  /* Choose 256 as the starting size of the hash table, somewhat arbitrarily.
+     The hash table code will round this up to the next prime number. 
+     Choosing a much larger table size wastes memory, and saves only about
+     1% in symbol reading.  */
+
+  objfile->demangled_names_hash = htab_create_alloc_ex
+    (256, htab_hash_string, (int (*) (const void *, const void *)) streq,
+     NULL, objfile->md, xmcalloc, xmfree);
+}
 
-/* Try to initialize the demangled name for a symbol, based on the
+/* Try to determine the demangled name for a symbol, based on the
    language of that symbol.  If the language is set to language_auto,
    it will attempt to find any demangling algorithm that works and
-   then set the language appropriately.  If no demangling of any kind
-   is found, the language is set back to language_unknown, so we can
-   avoid doing this work again the next time we encounter the symbol.
-   Any required space to store the name is obtained from the specified
-   obstack. */
+   then set the language appropriately.  The returned name is allocated
+   by the demangler and should be xfree'd.  */
 
-void
-symbol_init_demangled_name (struct general_symbol_info *gsymbol,
-                            struct obstack *obstack)
+static char *
+symbol_find_demangled_name (struct general_symbol_info *gsymbol,
+			    const char *mangled)
 {
-  char *mangled = gsymbol->name;
   char *demangled = NULL;
 
   if (gsymbol->language == language_unknown)
@@ -449,35 +464,116 @@ symbol_init_demangled_name (struct gener
       || gsymbol->language == language_auto)
     {
       demangled =
-        cplus_demangle (gsymbol->name, DMGL_PARAMS | DMGL_ANSI);
+        cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
       if (demangled != NULL)
-        {
-          gsymbol->language = language_cplus;
-          gsymbol->language_specific.cplus_specific.demangled_name =
-            obsavestring (demangled, strlen (demangled), obstack);
-          xfree (demangled);
-        }
-      else
-        {
-          gsymbol->language_specific.cplus_specific.demangled_name = NULL;
-        }
+	{
+	  gsymbol->language = language_cplus;
+	  return demangled;
+	}
     }
   if (gsymbol->language == language_java)
     {
       demangled =
-        cplus_demangle (gsymbol->name,
+        cplus_demangle (mangled,
                         DMGL_PARAMS | DMGL_ANSI | DMGL_JAVA);
       if (demangled != NULL)
-        {
-          gsymbol->language = language_java;
-          gsymbol->language_specific.cplus_specific.demangled_name =
-            obsavestring (demangled, strlen (demangled), obstack);
-          xfree (demangled);
-        }
+	{
+	  gsymbol->language = language_java;
+	  return demangled;
+	}
+    }
+  return NULL;
+}
+
+/* Set both the mangled and demangled (if any) names for GSYMBOL based on
+   NAME and LEN.  The hash table corresponding to OBJFILE is used, and the
+   memory comes from that objfile's symbol_obstack.  NAME is copied, so the
+   pointer can be discarded after calling this function.  */
+
+void
+symbol_set_names (struct general_symbol_info *gsymbol,
+		  const char *name, int len, struct objfile *objfile)
+{
+  char **slot;
+  const char *tmpname;
+
+  if (objfile->demangled_names_hash == NULL)
+    create_demangled_names_hash (objfile);
+
+  /* The stabs reader generally provides names that are not NULL-terminated;
+     most of the other readers don't do this, so we can just use the given
+     copy.  */
+  if (name[len] != 0)
+    {
+      char *alloc_name = alloca (len + 1);
+      memcpy (alloc_name, name, len);
+      alloc_name[len] = 0;
+      tmpname = alloc_name;
+    }
+  else
+    tmpname = name;
+
+  slot = (char **) htab_find_slot (objfile->demangled_names_hash, tmpname, INSERT);
+
+  /* If this name is not in the hash table, add it.  */
+  if (*slot == NULL)
+    {
+      char *demangled_name = symbol_find_demangled_name (gsymbol, tmpname);
+      int demangled_len = demangled_name ? strlen (demangled_name) : 0;
+
+      /* If there is a demangled name, place it right after the mangled name.
+	 Otherwise, just place a second zero byte after the end of the mangled
+	 name.  */
+      *slot = obstack_alloc (&objfile->symbol_obstack,
+			     len + demangled_len + 2);
+      memcpy (*slot, tmpname, len + 1);
+      if (demangled_name)
+	{
+	  memcpy (*slot + len + 1, demangled_name, demangled_len + 1);
+	  xfree (demangled_name);
+	}
       else
-        {
-          gsymbol->language_specific.cplus_specific.demangled_name = NULL;
-        }
+	(*slot)[len + 1] = 0;
+    }
+
+  gsymbol->name = *slot;
+  if ((*slot)[len + 1])
+    gsymbol->language_specific.cplus_specific.demangled_name
+      = &(*slot)[len + 1];
+  else
+    gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+}
+
+/* Initialize the demangled name of GSYMBOL if possible.  Any required space
+   to store the name is obtained from the specified obstack.  The function
+   symbol_set_names, above, should be used instead where possible for more
+   efficient memory usage.  */
+
+void
+symbol_init_demangled_name (struct general_symbol_info *gsymbol,
+                            struct obstack *obstack)
+{
+  char *mangled = gsymbol->name;
+  char *demangled = NULL;
+
+  demangled = symbol_find_demangled_name (gsymbol, mangled);
+  if (gsymbol->language == language_cplus
+      || gsymbol->language == language_java)
+    {
+      if (demangled)
+	{
+	  gsymbol->language_specific.cplus_specific.demangled_name
+	    = obsavestring (demangled, strlen (demangled), obstack);
+	  xfree (demangled);
+	}
+      else
+	gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+    }
+  else
+    {
+      /* Unknown language; just clean up quietly.  */
+      if (demangled)
+	xfree (demangled);
     }
 }
 
Index: symtab.h
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/symtab.h,v
retrieving revision 1.55
diff -u -p -r1.55 symtab.h
--- symtab.h	19 Jan 2003 04:06:46 -0000	1.55
+++ symtab.h	30 Jan 2003 01:05:47 -0000
@@ -149,9 +149,15 @@ extern void symbol_init_language_specifi
 					   enum language language);
 
 #define SYMBOL_INIT_DEMANGLED_NAME(symbol,obstack) \
-  (symbol_init_demangled_name (&symbol->ginfo, (obstack)))
+  (symbol_init_demangled_name (&(symbol)->ginfo, (obstack)))
 extern void symbol_init_demangled_name (struct general_symbol_info *symbol,
 					struct obstack *obstack);
+
+#define SYMBOL_SET_NAMES(symbol,name,len,objfile) \
+  symbol_set_names (&(symbol)->ginfo, name, len, objfile)
+extern void symbol_set_names (struct general_symbol_info *symbol,
+			      const char *name, int len,
+			      struct objfile *objfile);
 
 /* Return the demangled name for a symbol based on the language for
    that symbol.  If no demangled name exists, return NULL. */
Index: utils.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/utils.c,v
retrieving revision 1.90
diff -u -p -r1.90 utils.c
--- utils.c	23 Jan 2003 23:03:32 -0000	1.90
+++ utils.c	26 Jan 2003 20:17:13 -0000
@@ -2361,6 +2361,14 @@ strcmp_iw (const char *string1, const ch
     }
   return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0');
 }
+
+/* A simple comparison function with opposite semantics to strcmp.  */
+
+int
+streq (const char *lhs, const char *rhs)
+{
+  return !strcmp (lhs, rhs);
+}
 
 
 /*


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]