Re: RFC: Demangle partial symbols and save memory too

Jim Blandy
2003-01-28T23:57:49Z

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'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.)

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.

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.

> + *(*slot + len + 1) = 0;

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

Daniel Jacobowitz <drow@mvista.com> writes:

> Right now, partial symbols don't have their demangled names set. David
> Carlton mentioned to me that he wanted to have the demangled names available
> at this stage; there's a consistency benefit. We discussed several simple
> approaches and eventually came to the conclusion that the performance and
> memory hit was too much to take the naive approach.
>
> Someone had the bright idea that we've already got a copy of most of this
> information (don't remember whose idea it was). We demangle the names of
> the minimal symbols, and most partial symbols that we would be demangling
> have matching minimal symbols. Not to mention, we'll demangle them again
> when we read in full symbols.
>
> So I figured, the demangler is expensive (even after my unreviewed GCC patch
> to kill the memory leaks in it). So why not avoid it? Demangle the names
> only once, or at least only once per objfile. Hash them based on the
> mangled name.
>
> This also lets us uniquely share the symbol names between msyms, psyms, and
> full symbols. More memory savings, and we get the demangling for free.
>
> I introduced a new hash table for this; partial symbols used to put the
> partial symbols and their names into the same bcache, which is inefficient.
> I used libiberty's expanding hash table, because bcache didn't have the
> necessary interfaces.
>
> Net performance impact of this patch: Reading in full minimal/partial
> symbols for Mozilla (about 70MB of stabs, same testcase I've been using for
> a few weeks now) goes up .1 seconds (a little under 1%), and RAM goes down
> 6.5MB (a little over 10%). In addition we have demangled names available
> for the partial symbols, which will enable further cleanups. I think it's
> a reasonable tradeoff at this stage. Opinions?
>
> The size of the initial hash table is pretty arbitrary. If I raise it
> >From 256 to 1024, then memory usage goes up 250K and startup time goes down
> about 0.01 seconds. If I make it ridiculously large I get back the 1%
> startup time penalty, but I waste 10MB of memory. So I think this is at the
> right spot.
>
> I converted every user of SYMBOL_INIT_DEMANGLED_NAME except for hpread,
> because hpread has different memory allocation requirements; it doesn't want
> the extra copy of SYMBOL_NAME. It'll still save on partial symbols.
>
> This patch is somewhat invasive, so I plan to sit on it until probably next
> weekend for comments.
>
> [For those keeping score, I've knocked 20% off the memory usage for symbol
> reading so far today; I have about another 10% still in my bag before I call
> it quits. Maybe more, next time I review where all our memory is really
> going.]
>
> --
> Daniel Jacobowitz
> MontaVista Software Debian GNU/Linux Developer
>
> 2003-01-26 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: 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: 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 26 Jan 2003 20:17:13 -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,9 @@ 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. */
> + 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 26 Jan 2003 21:24:04 -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,36 +464,102 @@ 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,
> + char *name, int len, struct objfile *objfile)
> +{
> + char **slot;
> + char *tmpname;
> +
> + if (objfile->demangled_names_hash == NULL)
> + create_demangled_names_hash (objfile);
> +
> + if (name[len] != 0)
> + {
> + tmpname = alloca (len + 1);
> + memcpy (tmpname, name, len);
> + tmpname[len] = 0;
> + }
> + 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 (demangled)
> + {
> + gsymbol->language_specific.cplus_specific.demangled_name
> + = obsavestring (demangled, strlen (demangled), obstack);
> + xfree (demangled);
> + }
> + else
> + gsymbol->language_specific.cplus_specific.demangled_name = NULL;
> }
>
> /* Return the demangled name for a symbol based on the language for
> 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 26 Jan 2003 20:17:13 -0000
> @@ -149,9 +149,14 @@ 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, 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);
> +}
> \f
>
> /*
> 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: 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)
> {