* RFC: Demangle partial symbols and save memory too
@ 2003-01-26 22:27 Daniel Jacobowitz
2003-01-27 1:54 ` Paul N. Hilfinger
` (2 more replies)
0 siblings, 3 replies; 14+ messages in thread
From: Daniel Jacobowitz @ 2003-01-26 22:27 UTC (permalink / raw)
To: gdb-patches
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),
- ¤t_objfile->symbol_obstack);
SYMBOL_LANGUAGE (s) = psymtab_language;
- SYMBOL_INIT_DEMANGLED_NAME (s, ¤t_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)
{
case TAG_label:
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFC: Demangle partial symbols and save memory too
2003-01-26 22:27 RFC: Demangle partial symbols and save memory too Daniel Jacobowitz
@ 2003-01-27 1:54 ` Paul N. Hilfinger
2003-01-27 2:02 ` Daniel Jacobowitz
2003-01-27 18:53 ` David Carlton
2003-01-28 23:57 ` Jim Blandy
2 siblings, 1 reply; 14+ messages in thread
From: Paul N. Hilfinger @ 2003-01-27 1:54 UTC (permalink / raw)
To: drow; +Cc: gdb-patches
> 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.
While you're in there merging symbol strings, perhaps you can explain
this code from stabsread.c (there might be similar code for other
readers; I haven't looked): In define_symbol, handling of 'T' case:
if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
TYPE_TAG_NAME (SYMBOL_TYPE (sym))
= obconcat (&objfile->type_obstack, "", "", SYMBOL_NAME (sym));
Why can't just SYMBOL_NAME (sym) be used for the TYPE_TAG_NAME value?
Paul Hilfinger
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFC: Demangle partial symbols and save memory too
2003-01-27 1:54 ` Paul N. Hilfinger
@ 2003-01-27 2:02 ` Daniel Jacobowitz
0 siblings, 0 replies; 14+ messages in thread
From: Daniel Jacobowitz @ 2003-01-27 2:02 UTC (permalink / raw)
To: gdb-patches
On Sun, Jan 26, 2003 at 05:55:22PM -0800, Paul N. Hilfinger wrote:
>
> > 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.
>
> While you're in there merging symbol strings, perhaps you can explain
> this code from stabsread.c (there might be similar code for other
> readers; I haven't looked): In define_symbol, handling of 'T' case:
>
>
> if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
> TYPE_TAG_NAME (SYMBOL_TYPE (sym))
> = obconcat (&objfile->type_obstack, "", "", SYMBOL_NAME (sym));
>
> Why can't just SYMBOL_NAME (sym) be used for the TYPE_TAG_NAME value?
At a guess, the theory is because SYMBOL_NAME is on the symbol_obstack
and we can discard symbols when we can't necessarily discard types - if
I remember right, there's some other problems that interfere with
discarding types when we discard an objfile.
As I said, that's just a guess.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFC: Demangle partial symbols and save memory too
2003-01-26 22:27 RFC: Demangle partial symbols and save memory too Daniel Jacobowitz
2003-01-27 1:54 ` Paul N. Hilfinger
@ 2003-01-27 18:53 ` David Carlton
2003-01-27 19:00 ` Daniel Jacobowitz
2003-01-28 23:57 ` Jim Blandy
2 siblings, 1 reply; 14+ messages in thread
From: David Carlton @ 2003-01-27 18:53 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
On Sun, 26 Jan 2003 17:28:08 -0500, Daniel Jacobowitz <drow@mvista.com> said:
> 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.
Thanks for doing this; I really appreciate it. It will make my life
easier.
> +
> +/* 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)
Personally, I'd prefer that name be const char *. And, for that
matter, I'd rather have the demangled name member of struct
general_symbol_info be a const char *: it will be shared, so changing
it really would be bad. But that's really a separate issue; I'll
submit a patch for that one myself later.
> +{
> + 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;
Well, I like this better than the last time I saw it, but I'll still
give you a hard time. :-) You're assuming that name[len] is readable,
for the sake of an optimization that doesn't seem to me to have much
of a benefit (it could even be a pessimization if a high enough
proportion of names have name[len] nonzero, though that seems unlikely
to me). On the other hand, it does seem silly to copy the name if you
don't have to; a matter of taste, I suppose.
David Carlton
carlton@math.stanford.edu
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFC: Demangle partial symbols and save memory too
2003-01-27 18:53 ` David Carlton
@ 2003-01-27 19:00 ` Daniel Jacobowitz
2003-01-27 19:10 ` David Carlton
2003-01-27 21:21 ` Andrew Cagney
0 siblings, 2 replies; 14+ messages in thread
From: Daniel Jacobowitz @ 2003-01-27 19:00 UTC (permalink / raw)
To: gdb-patches
On Mon, Jan 27, 2003 at 10:53:35AM -0800, David Carlton wrote:
> On Sun, 26 Jan 2003 17:28:08 -0500, Daniel Jacobowitz <drow@mvista.com> said:
>
> > 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.
>
> Thanks for doing this; I really appreciate it. It will make my life
> easier.
>
> > +
> > +/* 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)
>
> Personally, I'd prefer that name be const char *. And, for that
> matter, I'd rather have the demangled name member of struct
> general_symbol_info be a const char *: it will be shared, so changing
> it really would be bad. But that's really a separate issue; I'll
> submit a patch for that one myself later.
Thanks for reminding me; I'll fix the first const char *. You'll
notice I fixed the ugly places I was modifying it already, from our
last discussion.
>
> > +{
> > + 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;
>
> Well, I like this better than the last time I saw it, but I'll still
> give you a hard time. :-) You're assuming that name[len] is readable,
> for the sake of an optimization that doesn't seem to me to have much
> of a benefit (it could even be a pessimization if a high enough
> proportion of names have name[len] nonzero, though that seems unlikely
> to me). On the other hand, it does seem silly to copy the name if you
> don't have to; a matter of taste, I suppose.
It's simple:
- stabs, name[len] will be readable but generally non-zero.
- everything else, name[len] will be zero.
Hmm, think it would be better to push the alloca out into the stabs
callers? Maybe that would work.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFC: Demangle partial symbols and save memory too
2003-01-27 19:00 ` Daniel Jacobowitz
@ 2003-01-27 19:10 ` David Carlton
2003-01-27 21:21 ` Andrew Cagney
1 sibling, 0 replies; 14+ messages in thread
From: David Carlton @ 2003-01-27 19:10 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
On Mon, 27 Jan 2003 14:01:09 -0500, Daniel Jacobowitz <drow@mvista.com> said:
> On Mon, Jan 27, 2003 at 10:53:35AM -0800, David Carlton wrote:
>> Personally, I'd prefer that name be const char *.
> Thanks for reminding me; I'll fix the first const char *. You'll
> notice I fixed the ugly places I was modifying it already, from our
> last discussion.
Yup!
>> Well, I like this better than the last time I saw it, but I'll still
>> give you a hard time. :-) You're assuming that name[len] is readable,
>> for the sake of an optimization that doesn't seem to me to have much
>> of a benefit (it could even be a pessimization if a high enough
>> proportion of names have name[len] nonzero, though that seems unlikely
>> to me). On the other hand, it does seem silly to copy the name if you
>> don't have to; a matter of taste, I suppose.
> It's simple:
> - stabs, name[len] will be readable but generally non-zero.
> - everything else, name[len] will be zero.
> Hmm, think it would be better to push the alloca out into the stabs
> callers? Maybe that would work.
Oh, I wouldn't go to that length unless you're particularly
motivated. Also, you'd have to change add_psymbol_to_list if you went
that way.
David Carlton
carlton@math.stanford.edu
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFC: Demangle partial symbols and save memory too
2003-01-27 19:00 ` Daniel Jacobowitz
2003-01-27 19:10 ` David Carlton
@ 2003-01-27 21:21 ` Andrew Cagney
2003-01-27 22:09 ` David Carlton
1 sibling, 1 reply; 14+ messages in thread
From: Andrew Cagney @ 2003-01-27 21:21 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
> Personally, I'd prefer that name be const char *. And, for that
>> matter, I'd rather have the demangled name member of struct
>> general_symbol_info be a const char *: it will be shared, so changing
>> it really would be bad. But that's really a separate issue; I'll
>> submit a patch for that one myself later.
>
>
> Thanks for reminding me; I'll fix the first const char *. You'll
> notice I fixed the ugly places I was modifying it already, from our
> last discussion.
Yes please! The more `char *' -> `const char *' stomping, the better.
Andrew
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFC: Demangle partial symbols and save memory too
2003-01-27 21:21 ` Andrew Cagney
@ 2003-01-27 22:09 ` David Carlton
2003-01-27 22:17 ` Andreas Schwab
0 siblings, 1 reply; 14+ messages in thread
From: David Carlton @ 2003-01-27 22:09 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Daniel Jacobowitz, gdb-patches
On Mon, 27 Jan 2003 16:21:46 -0500, Andrew Cagney <ac131313@redhat.com> said:
> The more `char *' -> `const char *' stomping, the better.
I spent some time on my branch trying to make this change quite
broadly (basically, turning name members of various structs into const
char *'s and dealing with the fallout). It ran into some serious
problems, though; I seem to recall that, ultimately, they came down to
decode_line_1 taking a char ** instead of a const char **. And
decode_line_1 really does (temporarily) change the characters that are
pointed to, unfortunately. So if we ever want to get this right
across the board, fixing decode_line_1 is probably the main
outstanding task.
I also toyed with trying to replace 'struct XXX *' with 'const struct
XXX *' wherever appropriate. That one's harder, though, because there
are structures in GDB where values are computed lazily and cached: so
not only are there functions that are logically const but not actually
const, but I also worried that making too many declarations const now
would inhibit such caching in the future. Maybe in a couple of years
we can switch GDB over to C++ instead of C and use 'mutable'...
David Carlton
carlton@math.stanford.edu
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFC: Demangle partial symbols and save memory too
2003-01-27 22:09 ` David Carlton
@ 2003-01-27 22:17 ` Andreas Schwab
2003-01-27 22:24 ` David Carlton
0 siblings, 1 reply; 14+ messages in thread
From: Andreas Schwab @ 2003-01-27 22:17 UTC (permalink / raw)
To: David Carlton; +Cc: Andrew Cagney, Daniel Jacobowitz, gdb-patches
David Carlton <carlton@math.stanford.edu> writes:
|> I also toyed with trying to replace 'struct XXX *' with 'const struct
|> XXX *' wherever appropriate. That one's harder, though, because there
|> are structures in GDB where values are computed lazily and cached: so
|> not only are there functions that are logically const but not actually
|> const, but I also worried that making too many declarations const now
|> would inhibit such caching in the future. Maybe in a couple of years
|> we can switch GDB over to C++ instead of C and use 'mutable'...
Even in C casting away const is OK as long as the object isn't read-only
in the first place. You just have to be careful to make sure this is not
violated.
Andreas.
--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFC: Demangle partial symbols and save memory too
2003-01-27 22:17 ` Andreas Schwab
@ 2003-01-27 22:24 ` David Carlton
2003-01-27 23:17 ` Andrew Cagney
0 siblings, 1 reply; 14+ messages in thread
From: David Carlton @ 2003-01-27 22:24 UTC (permalink / raw)
To: Andreas Schwab; +Cc: Andrew Cagney, Daniel Jacobowitz, gdb-patches
On Mon, 27 Jan 2003 23:17:55 +0100, Andreas Schwab <schwab@suse.de> said:
> David Carlton <carlton@math.stanford.edu> writes:
>> I also toyed with trying to replace 'struct XXX *' with 'const
>> struct XXX *' wherever appropriate. That one's harder, though,
>> because there are structures in GDB where values are computed
>> lazily and cached: so not only are there functions that are
>> logically const but not actually const, but I also worried that
>> making too many declarations const now would inhibit such caching
>> in the future. Maybe in a couple of years we can switch GDB over
>> to C++ instead of C and use 'mutable'...
> Even in C casting away const is OK as long as the object isn't
> read-only in the first place. You just have to be careful to make
> sure this is not violated.
That's a good point. I don't like casts, of course, but in this
particular situation my dislike of casts might be trumped by my liking
of const when logically appropriate.
David Carlton
carlton@math.stanford.edu
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFC: Demangle partial symbols and save memory too
2003-01-27 22:24 ` David Carlton
@ 2003-01-27 23:17 ` Andrew Cagney
0 siblings, 0 replies; 14+ messages in thread
From: Andrew Cagney @ 2003-01-27 23:17 UTC (permalink / raw)
To: David Carlton; +Cc: Andreas Schwab, Daniel Jacobowitz, gdb-patches
> On Mon, 27 Jan 2003 23:17:55 +0100, Andreas Schwab <schwab@suse.de> said:
>
>> David Carlton <carlton@math.stanford.edu> writes:
>
>
>>> I also toyed with trying to replace 'struct XXX *' with 'const
>>> struct XXX *' wherever appropriate. That one's harder, though,
>>> because there are structures in GDB where values are computed
>>> lazily and cached: so not only are there functions that are
>>> logically const but not actually const, but I also worried that
>>> making too many declarations const now would inhibit such caching
>>> in the future. Maybe in a couple of years we can switch GDB over
>>> to C++ instead of C and use 'mutable'...
>
>
>> Even in C casting away const is OK as long as the object isn't
>> read-only in the first place. You just have to be careful to make
>> sure this is not violated.
>
>
> That's a good point. I don't like casts, of course, but in this
> particular situation my dislike of casts might be trumped by my liking
> of const when logically appropriate.
I'd rather not see such casts. It is easier to recommend no casts then
to recommend no casts `but'.
The current objective for const is just with strings - getting GDB past
-Wwriteable-strings so that we know that all constant strings can be
moved to the text segment.
Andrew
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFC: Demangle partial symbols and save memory too
2003-01-26 22:27 RFC: Demangle partial symbols and save memory too Daniel Jacobowitz
2003-01-27 1:54 ` Paul N. Hilfinger
2003-01-27 18:53 ` David Carlton
@ 2003-01-28 23:57 ` Jim Blandy
2003-01-30 1:16 ` Daniel Jacobowitz
2 siblings, 1 reply; 14+ messages in thread
From: Jim Blandy @ 2003-01-28 23:57 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
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),
> - ¤t_objfile->symbol_obstack);
> SYMBOL_LANGUAGE (s) = psymtab_language;
> - SYMBOL_INIT_DEMANGLED_NAME (s, ¤t_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)
> {
> case TAG_label:
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFC: Demangle partial symbols and save memory too
2003-01-28 23:57 ` Jim Blandy
@ 2003-01-30 1:16 ` Daniel Jacobowitz
2003-02-04 18:07 ` Daniel Jacobowitz
0 siblings, 1 reply; 14+ messages in thread
From: Daniel Jacobowitz @ 2003-01-30 1:16 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb-patches
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),
- ¤t_objfile->symbol_obstack);
SYMBOL_LANGUAGE (s) = psymtab_language;
- SYMBOL_INIT_DEMANGLED_NAME (s, ¤t_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);
+}
\f
/*
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: RFC: Demangle partial symbols and save memory too
2003-01-30 1:16 ` Daniel Jacobowitz
@ 2003-02-04 18:07 ` Daniel Jacobowitz
0 siblings, 0 replies; 14+ messages in thread
From: Daniel Jacobowitz @ 2003-02-04 18:07 UTC (permalink / raw)
To: gdb-patches; +Cc: Jim Blandy
I've checked this in, with David's and Jim's comments incorporated, and
copyright dates updated.
On Wed, Jan 29, 2003 at 08:17:22PM -0500, Daniel Jacobowitz wrote:
> I also fixed up some consts that David pointed out; here's an update.
> 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.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2003-02-04 18:07 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-01-26 22:27 RFC: Demangle partial symbols and save memory too Daniel Jacobowitz
2003-01-27 1:54 ` Paul N. Hilfinger
2003-01-27 2:02 ` Daniel Jacobowitz
2003-01-27 18:53 ` David Carlton
2003-01-27 19:00 ` Daniel Jacobowitz
2003-01-27 19:10 ` David Carlton
2003-01-27 21:21 ` Andrew Cagney
2003-01-27 22:09 ` David Carlton
2003-01-27 22:17 ` Andreas Schwab
2003-01-27 22:24 ` David Carlton
2003-01-27 23:17 ` Andrew Cagney
2003-01-28 23:57 ` Jim Blandy
2003-01-30 1:16 ` Daniel Jacobowitz
2003-02-04 18:07 ` Daniel Jacobowitz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox