* bcache.c, bcache.h: New files to implement a byte cache.

* Makefile.in (SFILES): Add bcache.c.
	(symtab_h): Add bcache.h.
	(HFILES_NO_SRCDIR): add bcache.h
	(COMMON_OBJS): Add bcache.o
	(bcache.o): New target.
	* dbxread.c (start_psymtab): Make global_syms & static_syms
 	type "partial_symbol **".
	* hpread.c (hpread_start_symtab):  Ditto.
	* os9kread.c (os9k_start_psymtab):  Ditto.
	* stabsread.h (start_psymtab):  Ditto.
	* {symfile.c, symfile.h} (start_psymtab_common):  Ditto.
	* maint.c (maintenance_print_statistics): Call
 	print_symbol_bcache_statistics.
	* objfiles.c (allocate_objfile): Initialize psymbol bcache malloc
	and free pointers.
	* solib.c (allocate_rt_common_objfile): Ditto.
	* symfile.c (reread_symbols):  Ditto.
	(free_objfile): Free psymbol bcache when objfile is freed.
	(objfile_relocate): Use new indirect psymbol pointers.
	* objfiles.h (struct objfile): Add psymbol cache.
	* symfile.c (compare_psymbols): Now passed pointers to pointers to
	psymbols.
	(reread_symbols): Free psymbol bcache when freeing other objfile
	resources.
	(add_psymbol_to_list, add_psymbol_addr_to_list): Initialize new
	psymbol using the psymbol bcache.
	(init_psymbol_list): Psymbol lists now contain pointers rather than
	the actual psymbols.
	* symfile.h (psymbol_allocation_list): Psymbol lists now dynamically
	grown arrays of pointers.
	(ADD_PSYMBOL_VT_TO_LIST): Initialize new symbol using the psymbol
	bcache.
	* symmisc.c (print_partial_symbols): Now takes pointer to pointer
	to partial symbol.
	(print_symbol_bcache_statistics): New function to print per objfile
 	bcache statistics.
	(print_partial_symbol, print_partial_symbols,
 	maintenance_check_symtabs, extend_psymbol_list):
 	Account for change to pointer to pointer to partial symbol.
	* symtab.c (find_pc_psymbol, lookup_partial_symbol, decode_line_2,
	make_symbol_completion_list):
 	Account for change to pointer to pointer to partial symbol.
	* symtab.h (bcache.h): Include.
	* xcoffread.c (xcoff_start_psymtab): Make global_syms & static_syms
 	type "partial_symbol **".
This commit is contained in:
Fred Fish 1996-02-16 22:14:47 +00:00
parent ef2074c25a
commit 2ad5709f00
16 changed files with 456 additions and 113 deletions

View File

@ -1,3 +1,52 @@
Fri Feb 16 14:00:54 1996 Fred Fish <fnf@cygnus.com>
* bcache.c, bcache.h: New files to implement a byte cache.
* Makefile.in (SFILES): Add bcache.c.
(symtab_h): Add bcache.h.
(HFILES_NO_SRCDIR): add bcache.h
(COMMON_OBJS): Add bcache.o
(bcache.o): New target.
* dbxread.c (start_psymtab): Make global_syms & static_syms
type "partial_symbol **".
* hpread.c (hpread_start_symtab): Ditto.
* os9kread.c (os9k_start_psymtab): Ditto.
* stabsread.h (start_psymtab): Ditto.
* {symfile.c, symfile.h} (start_psymtab_common): Ditto.
* maint.c (maintenance_print_statistics): Call
print_symbol_bcache_statistics.
* objfiles.c (allocate_objfile): Initialize psymbol bcache malloc
and free pointers.
* solib.c (allocate_rt_common_objfile): Ditto.
* symfile.c (reread_symbols): Ditto.
(free_objfile): Free psymbol bcache when objfile is freed.
(objfile_relocate): Use new indirect psymbol pointers.
* objfiles.h (struct objfile): Add psymbol cache.
* symfile.c (compare_psymbols): Now passed pointers to pointers to
psymbols.
(reread_symbols): Free psymbol bcache when freeing other objfile
resources.
(add_psymbol_to_list, add_psymbol_addr_to_list): Initialize new
psymbol using the psymbol bcache.
(init_psymbol_list): Psymbol lists now contain pointers rather than
the actual psymbols.
* symfile.h (psymbol_allocation_list): Psymbol lists now dynamically
grown arrays of pointers.
(ADD_PSYMBOL_VT_TO_LIST): Initialize new symbol using the psymbol
bcache.
* symmisc.c (print_partial_symbols): Now takes pointer to pointer
to partial symbol.
(print_symbol_bcache_statistics): New function to print per objfile
bcache statistics.
(print_partial_symbol, print_partial_symbols,
maintenance_check_symtabs, extend_psymbol_list):
Account for change to pointer to pointer to partial symbol.
* symtab.c (find_pc_psymbol, lookup_partial_symbol, decode_line_2,
make_symbol_completion_list):
Account for change to pointer to pointer to partial symbol.
* symtab.h (bcache.h): Include.
* xcoffread.c (xcoff_start_psymtab): Make global_syms & static_syms
type "partial_symbol **".
Fri Feb 16 10:02:34 1996 Fred Fish <fnf@cygnus.com>
* dwarfread.c (free_utypes): New function.

View File

@ -145,7 +145,6 @@ ENABLE_CFLAGS= @ENABLE_CFLAGS@
ENABLE_CLIBS= @ENABLE_CLIBS@
ENABLE_OBS= @ENABLE_OBS@
# -I. for config files.
# -I$(srcdir) for gdb internal headers and possibly for gnu-regex.h also.
# -I$(srcdir)/config for more generic config files.
@ -197,10 +196,11 @@ REGEX1 = gnu-regex.o
# If you have the Cygnus libraries installed,
# you can use 'CLIBS=$(INSTALLED_LIBS)' 'CDEPS='
INSTALLED_LIBS=-lbfd -lreadline $(TERMCAP) -lopcodes -lmmalloc \
-liberty $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(ENABLE_CLIBS)
-liberty $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(ENABLE_CLIBS) \
@LIBS@
CLIBS = $(SIM) $(BFD) $(READLINE) $(OPCODES) $(MMALLOC) $(LIBIBERTY) \
$(ENABLE_CLIBS) $(TERMCAP) $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) \
$(LIBIBERTY) $(LIBS)
$(LIBIBERTY) @LIBS@
CDEPS = $(XM_CDEPS) $(TM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE) \
$(OPCODES) $(MMALLOC) $(LIBIBERTY)
@ -345,10 +345,10 @@ TARGET_FLAGS_TO_PASS = \
# Links made at configuration time should not be specified here, since
# SFILES is used in building the distribution archive.
SFILES = blockframe.c breakpoint.c buildsym.c callback.c c-exp.y c-lang.c \
c-typeprint.c c-valprint.c ch-exp.c ch-lang.c ch-typeprint.c \
ch-valprint.c coffread.c command.c complaints.c corefile.c cp-valprint.c \
dbxread.c demangle.c dwarfread.c \
SFILES = bcache.c blockframe.c breakpoint.c buildsym.c callback.c c-exp.y \
c-lang.c c-typeprint.c c-valprint.c ch-exp.c ch-lang.c \
ch-typeprint.c ch-valprint.c coffread.c command.c complaints.c \
corefile.c cp-valprint.c dbxread.c demangle.c dwarfread.c \
elfread.c environ.c eval.c expprint.c \
f-exp.y f-lang.c f-typeprint.c f-valprint.c findvar.c \
gdbtypes.c infcmd.c inflow.c infrun.c language.c \
@ -393,7 +393,7 @@ udiheaders = \
gdbcore_h = gdbcore.h $(bfd_h)
frame_h = frame.h
symtab_h = symtab.h
symtab_h = symtab.h bcache.h
gdbtypes_h = gdbtypes.h
expression_h = expression.h
value_h = value.h $(symtab_h) $(gdbtypes_h) $(expression_h)
@ -413,8 +413,8 @@ inferior_h = inferior.h $(breakpoint_h)
# wrong if TAGS has files twice). Because this is tricky to get
# right, it is probably easiest just to list .h files here directly.
HFILES_NO_SRCDIR = buildsym.h call-cmds.h coff-solib.h defs.h dst.h environ.h \
$(gdbcmd_h) gdbcore.h \
HFILES_NO_SRCDIR = bcache.h buildsym.h call-cmds.h coff-solib.h defs.h \
dst.h environ.h $(gdbcmd_h) gdbcore.h \
gdb-stabs.h $(inferior_h) language.h minimon.h monitor.h \
objfiles.h parser-defs.h partial-stab.h serial.h signals.h solib.h \
symfile.h stabsread.h target.h terminal.h typeprint.h xcoffsolib.h \
@ -461,7 +461,7 @@ COMMON_OBS = version.o blockframe.o breakpoint.o findvar.o stack.o thread.o \
symtab.o symfile.o symmisc.o infcmd.o infrun.o command.o \
expprint.o environ.o gdbtypes.o copying.o $(DEPFILES) \
mem-break.o target.o parse.o language.o $(YYOBJ) buildsym.o \
exec.o objfiles.o minsyms.o maint.o demangle.o \
exec.o bcache.o objfiles.o minsyms.o maint.o demangle.o \
dbxread.o coffread.o elfread.o \
dwarfread.o mipsread.o stabsread.o corefile.o \
c-lang.o ch-exp.o ch-lang.o f-lang.o m2-lang.o \
@ -743,7 +743,7 @@ maintainer-clean realclean: clean
rm -f Makefile
diststuff: $(DISTSTUFF)
cd doc; $(MAKE) $(MFLAGS) diststuff
cd doc; $(MAKE) $(MFLAGS) all-doc
subdir_do: force
@for i in $(DODIRS); do \
@ -998,6 +998,8 @@ annotate.o: annotate.c $(defs_h) annotate.h $(value_h) target.h $(gdbtypes_h)
arm-tdep.o: arm-tdep.c $(gdbcmd_h) $(gdbcore_h) $(inferior_h) $(defs_h)
bcache.o: bcache.c bcache.h $(defs_h)
blockframe.o: blockframe.c $(defs_h) $(gdbcore_h) $(inferior_h) \
objfiles.h symfile.h target.h

View File

@ -3,6 +3,12 @@
*** Changes since GDB-4.15:
* Memory use reductions and statistics collection
We have begun to implement changes that reduce gdb's memory requirements
and to report statistics about memory usage. Try the "maint print statistics"
command, for example.
* New native configurations
Windows 95, Windows NT i[345]86-*-win32

188
gdb/bcache.c Normal file
View File

@ -0,0 +1,188 @@
/* Implement a cached obstack.
Written by Fred Fish (fnf@cygnus.com)
Copyright 1995 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "obstack.h"
#include "bcache.h"
/* FIXME: Incredibly simplistic hash generator. Probably way too expensive
(consider long strings) and unlikely to have good distribution across hash
values for typical input. */
static unsigned int
hash (bytes, count)
void *bytes;
int count;
{
unsigned int len;
unsigned long hashval;
unsigned int c;
const unsigned char *data = bytes;
hashval = 0;
len = 0;
while (count-- > 0)
{
c = *data++;
hashval += c + (c << 17);
hashval ^= hashval >> 2;
++len;
}
hashval += len + (len << 17);
hashval ^= hashval >> 2;
return (hashval % BCACHE_HASHSIZE);
}
static void *
lookup_cache (bytes, count, hashval, bcachep)
void *bytes;
int count;
int hashval;
struct bcache *bcachep;
{
void *location = NULL;
struct hashlink **hashtablep;
struct hashlink *linkp;
hashtablep = bcachep -> indextable[count];
if (hashtablep != NULL)
{
linkp = hashtablep[hashval];
while (linkp != NULL)
{
if (memcmp (linkp -> data, bytes, count) == 0)
{
location = linkp -> data;
break;
}
linkp = linkp -> next;
}
}
return (location);
}
void *
bcache (bytes, count, bcachep)
void *bytes;
int count;
struct bcache *bcachep;
{
int hashval;
void *location;
struct hashlink *newlink;
struct hashlink **linkpp;
struct hashlink ***hashtablepp;
if (count > BCACHE_MAXLENGTH)
{
/* Rare enough to just stash unique copies */
location = (void *) obstack_alloc (&bcachep->cache, count);
bcachep -> cache_bytes += count;
memcpy (location, bytes, count);
bcachep -> bcache_overflows++;
}
else
{
hashval = hash (bytes, count);
location = lookup_cache (bytes, count, hashval, bcachep);
if (location != NULL)
{
bcachep -> cache_savings += count;
bcachep -> cache_hits++;
}
else
{
bcachep -> cache_misses++;
hashtablepp = &bcachep -> indextable[count];
if (*hashtablepp == NULL)
{
*hashtablepp = (struct hashlink **)
obstack_alloc (&bcachep->cache, BCACHE_HASHSIZE * sizeof (struct hashlink *));
bcachep -> cache_bytes += sizeof (struct hashlink *);
memset (*hashtablepp, 0, BCACHE_HASHSIZE * sizeof (struct hashlink *));
}
linkpp = &(*hashtablepp)[hashval];
newlink = (struct hashlink *)
obstack_alloc (&bcachep->cache, sizeof (struct hashlink *) + count);
bcachep -> cache_bytes += sizeof (struct hashlink *) + count;
memcpy (newlink -> data, bytes, count);
newlink -> next = *linkpp;
*linkpp = newlink;
location = newlink -> data;
}
}
return (location);
}
#if MAINTENANCE_CMDS
void
print_bcache_statistics (bcachep, id)
struct bcache *bcachep;
char *id;
{
struct hashlink **hashtablep;
struct hashlink *linkp;
int tidx, tcount, hidx, hcount, lcount, lmax, temp, lmaxt, lmaxh;
for (lmax = lcount = tcount = hcount = tidx = 0; tidx < BCACHE_MAXLENGTH; tidx++)
{
hashtablep = bcachep -> indextable[tidx];
if (hashtablep != NULL)
{
tcount++;
for (hidx = 0; hidx < BCACHE_HASHSIZE; hidx++)
{
linkp = hashtablep[hidx];
if (linkp != NULL)
{
hcount++;
for (temp = 0; linkp != NULL; linkp = linkp -> next)
{
lcount++;
temp++;
}
if (temp > lmax)
{
lmax = temp;
lmaxt = tidx;
lmaxh = hidx;
}
}
}
}
}
printf_filtered (" Cached '%s' statistics:\n", id);
printf_filtered (" Cache hits: %d\n", bcachep -> cache_hits);
printf_filtered (" Cache misses: %d\n", bcachep -> cache_misses);
printf_filtered (" Cache hit ratio: %d%%\n", ((bcachep -> cache_hits) * 100) / (bcachep -> cache_hits + bcachep -> cache_misses));
printf_filtered (" Space used for caching: %d\n", bcachep -> cache_bytes);
printf_filtered (" Space saved by cache hits: %d\n", bcachep -> cache_savings);
printf_filtered (" Number of bcache overflows: %d\n", bcachep -> bcache_overflows);
printf_filtered (" Number of index buckets used: %d\n", tcount);
printf_filtered (" Number of hash table buckets used: %d\n", hcount);
printf_filtered (" Number of chained items: %d\n", lcount);
printf_filtered (" Average hash table population: %d%%\n",
(hcount * 100) / (tcount * BCACHE_HASHSIZE));
printf_filtered (" Average chain length %d\n", lcount / hcount);
printf_filtered (" Maximum chain length %d at %d:%d\n", lmax, lmaxt, lmaxh);
}
#endif /* MAINTENANCE_CMDS */

46
gdb/bcache.h Normal file
View File

@ -0,0 +1,46 @@
/* Include file cached obstack implementation.
Written by Fred Fish (fnf@cygnus.com)
Copyright 1995 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef BCACHE_H
#define BCACHE_H 1
#define BCACHE_HASHLENGTH 12 /* Number of bits in hash value */
#define BCACHE_HASHSIZE (1 << BCACHE_HASHLENGTH)
#define BCACHE_MAXLENGTH 128
struct hashlink {
struct hashlink *next;
char data[1];
};
struct bcache {
struct obstack cache;
struct hashlink **indextable[BCACHE_MAXLENGTH];
int cache_hits;
int cache_misses;
int cache_bytes;
int cache_savings;
int bcache_overflows;
};
extern void *
bcache PARAMS ((void *bytes, int count, struct bcache *bcachep));
#endif /* BCACHE_H */

View File

@ -160,7 +160,7 @@ void hpread_symfile_finish PARAMS ((struct objfile *));
static struct partial_symtab *hpread_start_psymtab
PARAMS ((struct objfile *, struct section_offsets *, char *, CORE_ADDR, int,
struct partial_symbol *, struct partial_symbol *));
struct partial_symbol **, struct partial_symbol **));
static struct partial_symtab *hpread_end_psymtab
PARAMS ((struct partial_symtab *, char **, int, int, CORE_ADDR,
@ -827,8 +827,8 @@ hpread_start_psymtab (objfile, section_offsets,
char *filename;
CORE_ADDR textlow;
int ldsymoff;
struct partial_symbol *global_syms;
struct partial_symbol *static_syms;
struct partial_symbol **global_syms;
struct partial_symbol **static_syms;
{
struct partial_symtab *result =
start_psymtab_common (objfile, section_offsets,

View File

@ -249,7 +249,10 @@ maintenance_print_statistics (args, from_tty)
char *args;
int from_tty;
{
int temp;
print_objfile_statistics ();
print_symbol_bcache_statistics ();
}
/* The "maintenance print" command is defined as a prefix, with allow_unknown

View File

@ -159,6 +159,8 @@ allocate_objfile (abfd, mapped)
objfile -> md = md;
objfile -> mmfd = fd;
/* Update pointers to functions to *our* copies */
obstack_chunkfun (&objfile -> psymbol_cache.cache, xmmalloc);
obstack_freefun (&objfile -> psymbol_cache.cache, mfree);
obstack_chunkfun (&objfile -> psymbol_obstack, xmmalloc);
obstack_freefun (&objfile -> psymbol_obstack, mfree);
obstack_chunkfun (&objfile -> symbol_obstack, xmmalloc);
@ -186,6 +188,9 @@ allocate_objfile (abfd, mapped)
objfile -> mmfd = fd;
objfile -> flags |= OBJF_MAPPED;
mmalloc_setkey (objfile -> md, 0, objfile);
obstack_specify_allocation_with_arg (&objfile -> psymbol_cache.cache,
0, 0, xmmalloc, mfree,
objfile -> md);
obstack_specify_allocation_with_arg (&objfile -> psymbol_obstack,
0, 0, xmmalloc, mfree,
objfile -> md);
@ -228,6 +233,8 @@ allocate_objfile (abfd, mapped)
objfile = (struct objfile *) xmalloc (sizeof (struct objfile));
memset (objfile, 0, sizeof (struct objfile));
objfile -> md = NULL;
obstack_specify_allocation (&objfile -> psymbol_cache.cache, 0, 0,
xmalloc, free);
obstack_specify_allocation (&objfile -> psymbol_obstack, 0, 0, xmalloc,
free);
obstack_specify_allocation (&objfile -> symbol_obstack, 0, 0, xmalloc,
@ -433,6 +440,7 @@ free_objfile (objfile)
if (objfile->static_psymbols.list)
mfree (objfile->md, objfile->static_psymbols.list);
/* Free the obstacks for non-reusable objfiles */
obstack_free (&objfile -> psymbol_cache.cache, 0);
obstack_free (&objfile -> psymbol_obstack, 0);
obstack_free (&objfile -> symbol_obstack, 0);
obstack_free (&objfile -> type_obstack, 0);
@ -552,18 +560,18 @@ objfile_relocate (objfile, new_offsets)
}
{
struct partial_symbol *psym;
struct partial_symbol **psym;
for (psym = objfile->global_psymbols.list;
psym < objfile->global_psymbols.next;
psym++)
if (SYMBOL_SECTION (psym) >= 0)
SYMBOL_VALUE_ADDRESS (psym) += ANOFFSET (delta, SYMBOL_SECTION (psym));
if (SYMBOL_SECTION (*psym) >= 0)
SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta, SYMBOL_SECTION (*psym));
for (psym = objfile->static_psymbols.list;
psym < objfile->static_psymbols.next;
psym++)
if (SYMBOL_SECTION (psym) >= 0)
SYMBOL_VALUE_ADDRESS (psym) += ANOFFSET (delta, SYMBOL_SECTION (psym));
if (SYMBOL_SECTION (*psym) >= 0)
SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta, SYMBOL_SECTION (*psym));
}
{

View File

@ -252,6 +252,11 @@ struct objfile
struct obstack symbol_obstack; /* Full symbols */
struct obstack type_obstack; /* Types */
/* A byte cache where we can stash arbitrary "chunks" of bytes that
will not change. */
struct bcache psymbol_cache; /* Byte cache for partial syms */
/* Vectors of all partial symbols read in from file. The actual data
is stored in the psymbol_obstack. */

View File

@ -159,8 +159,8 @@ os9k_process_one_symbol PARAMS ((int, int, CORE_ADDR, char *,
static struct partial_symtab *
os9k_start_psymtab PARAMS ((struct objfile *, struct section_offsets *, char *,
CORE_ADDR, int, int, struct partial_symbol *,
struct partial_symbol *));
CORE_ADDR, int, int, struct partial_symbol **,
struct partial_symbol **));
static struct partial_symtab *
os9k_end_psymtab PARAMS ((struct partial_symtab *, char **, int, int, CORE_ADDR,
@ -972,8 +972,8 @@ os9k_start_psymtab (objfile, section_offsets,
CORE_ADDR textlow;
int ldsymoff;
int ldsymcnt;
struct partial_symbol *global_syms;
struct partial_symbol *static_syms;
struct partial_symbol **global_syms;
struct partial_symbol **static_syms;
{
struct partial_symtab *result =
start_psymtab_common(objfile, section_offsets,

View File

@ -183,8 +183,8 @@ struct stab_section_list
extern struct partial_symtab *
start_psymtab PARAMS ((struct objfile *, struct section_offsets *, char *,
CORE_ADDR, int, struct partial_symbol *,
struct partial_symbol *));
CORE_ADDR, int, struct partial_symbol **,
struct partial_symbol **));
extern struct partial_symtab *
end_psymtab PARAMS ((struct partial_symtab *, char **, int, int, CORE_ADDR,

View File

@ -148,9 +148,9 @@ LOCAL FUNCTION
DESCRIPTION
Given pointer to two partial symbol table entries, compare
them by name and return -N, 0, or +N (ala strcmp). Typically
used by sorting routines like qsort().
Given pointers to pointers to two partial symbol table entries,
compare them by name and return -N, 0, or +N (ala strcmp).
Typically used by sorting routines like qsort().
NOTES
@ -167,8 +167,8 @@ compare_psymbols (s1p, s2p)
const PTR s1p;
const PTR s2p;
{
register char *st1 = SYMBOL_NAME ((struct partial_symbol *) s1p);
register char *st2 = SYMBOL_NAME ((struct partial_symbol *) s2p);
register char *st1 = SYMBOL_NAME (*(struct partial_symbol **) s1p);
register char *st2 = SYMBOL_NAME (*(struct partial_symbol **) s2p);
if ((st1[0] - st2[0]) || !st1[0])
{
@ -191,7 +191,7 @@ sort_pst_symbols (pst)
/* Sort the global list; don't sort the static list */
qsort (pst -> objfile -> global_psymbols.list + pst -> globals_offset,
pst -> n_global_syms, sizeof (struct partial_symbol),
pst -> n_global_syms, sizeof (struct partial_symbol *),
compare_psymbols);
}
@ -1192,6 +1192,7 @@ reread_symbols ()
objfile->static_psymbols.size = 0;
/* Free the obstacks for non-reusable objfiles */
obstack_free (&objfile -> psymbol_cache.cache, 0);
obstack_free (&objfile -> psymbol_obstack, 0);
obstack_free (&objfile -> symbol_obstack, 0);
obstack_free (&objfile -> type_obstack, 0);
@ -1211,6 +1212,8 @@ reread_symbols ()
objfile -> md = NULL;
/* obstack_specify_allocation also initializes the obstack so
it is empty. */
obstack_specify_allocation (&objfile -> psymbol_cache.cache, 0, 0,
xmalloc, free);
obstack_specify_allocation (&objfile -> psymbol_obstack, 0, 0,
xmalloc, free);
obstack_specify_allocation (&objfile -> symbol_obstack, 0, 0,
@ -1616,8 +1619,8 @@ start_psymtab_common (objfile, section_offsets,
struct section_offsets *section_offsets;
char *filename;
CORE_ADDR textlow;
struct partial_symbol *global_syms;
struct partial_symbol *static_syms;
struct partial_symbol **global_syms;
struct partial_symbol **static_syms;
{
struct partial_symtab *psymtab;
@ -1651,24 +1654,29 @@ add_psymbol_to_list (name, namelength, namespace, class, list, val, language,
struct objfile *objfile;
{
register struct partial_symbol *psym;
register char *demangled_name;
char *buf = alloca (namelength + 1);
struct partial_symbol psymbol;
/* Create local copy of the partial symbol */
memcpy (buf, name, namelength);
buf[namelength] = '\0';
SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, &objfile->psymbol_cache);
SYMBOL_VALUE (&psymbol) = val;
SYMBOL_SECTION (&psymbol) = 0;
SYMBOL_LANGUAGE (&psymbol) = language;
PSYMBOL_NAMESPACE (&psymbol) = namespace;
PSYMBOL_CLASS (&psymbol) = class;
SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language);
/* Stash the partial symbol away in the cache */
psym = bcache (&psymbol, sizeof (struct partial_symbol), &objfile->psymbol_cache);
/* Save pointer to partial symbol in psymtab, growing symtab if needed. */
if (list->next >= list->list + list->size)
{
extend_psymbol_list (list,objfile);
extend_psymbol_list (list, objfile);
}
psym = list->next++;
SYMBOL_NAME (psym) =
(char *) obstack_alloc (&objfile->psymbol_obstack, namelength + 1);
memcpy (SYMBOL_NAME (psym), name, namelength);
SYMBOL_NAME (psym)[namelength] = '\0';
SYMBOL_VALUE (psym) = val;
SYMBOL_SECTION (psym) = 0;
SYMBOL_LANGUAGE (psym) = language;
PSYMBOL_NAMESPACE (psym) = namespace;
PSYMBOL_CLASS (psym) = class;
SYMBOL_INIT_LANGUAGE_SPECIFIC (psym, language);
*list->next++ = psym;
OBJSTAT (objfile, n_psyms++);
}
@ -1687,24 +1695,29 @@ add_psymbol_addr_to_list (name, namelength, namespace, class, list, val,
struct objfile *objfile;
{
register struct partial_symbol *psym;
register char *demangled_name;
char *buf = alloca (namelength + 1);
struct partial_symbol psymbol;
/* Create local copy of the partial symbol */
memcpy (buf, name, namelength);
buf[namelength] = '\0';
SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, &objfile->psymbol_cache);
SYMBOL_VALUE_ADDRESS (&psymbol) = val;
SYMBOL_SECTION (&psymbol) = 0;
SYMBOL_LANGUAGE (&psymbol) = language;
PSYMBOL_NAMESPACE (&psymbol) = namespace;
PSYMBOL_CLASS (&psymbol) = class;
SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language);
/* Stash the partial symbol away in the cache */
psym = bcache (&psymbol, sizeof (struct partial_symbol), &objfile->psymbol_cache);
/* Save pointer to partial symbol in psymtab, growing symtab if needed. */
if (list->next >= list->list + list->size)
{
extend_psymbol_list (list,objfile);
extend_psymbol_list (list, objfile);
}
psym = list->next++;
SYMBOL_NAME (psym) =
(char *) obstack_alloc (&objfile->psymbol_obstack, namelength + 1);
memcpy (SYMBOL_NAME (psym), name, namelength);
SYMBOL_NAME (psym)[namelength] = '\0';
SYMBOL_VALUE_ADDRESS (psym) = val;
SYMBOL_SECTION (psym) = 0;
SYMBOL_LANGUAGE (psym) = language;
PSYMBOL_NAMESPACE (psym) = namespace;
PSYMBOL_CLASS (psym) = class;
SYMBOL_INIT_LANGUAGE_SPECIFIC (psym, language);
*list->next++ = psym;
OBJSTAT (objfile, n_psyms++);
}
@ -1735,13 +1748,13 @@ init_psymbol_list (objfile, total_symbols)
objfile -> global_psymbols.size = total_symbols / 10;
objfile -> static_psymbols.size = total_symbols / 10;
objfile -> global_psymbols.next =
objfile -> global_psymbols.list = (struct partial_symbol *)
objfile -> global_psymbols.list = (struct partial_symbol **)
xmmalloc (objfile -> md, objfile -> global_psymbols.size
* sizeof (struct partial_symbol));
* sizeof (struct partial_symbol *));
objfile -> static_psymbols.next =
objfile -> static_psymbols.list = (struct partial_symbol *)
objfile -> static_psymbols.list = (struct partial_symbol **)
xmmalloc (objfile -> md, objfile -> static_psymbols.size
* sizeof (struct partial_symbol));
* sizeof (struct partial_symbol *));
}
void

View File

@ -23,10 +23,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* This file requires that you first include "bfd.h". */
/* Partial symbols are stored in the psymbol_cache and pointers to them
are kept in a dynamically grown array that is obtained from malloc and
grown as necessary via realloc. Each objfile typically has two of these,
one for global symbols and one for static symbols. Although this adds
a level of indirection for storing or accessing the partial symbols,
it allows us to throw away duplicate psymbols and set all pointers
to the single saved instance. */
struct psymbol_allocation_list {
struct partial_symbol *list;
struct partial_symbol *next;
int size;
struct partial_symbol **list; /* Pointer to first partial symbol pointer*/
struct partial_symbol **next; /* Pointer to next avail storage for pointer */
int size; /* Number of symbols */
};
/* Structure to keep track of symbol reading functions for various
@ -116,21 +124,22 @@ extend_psymbol_list PARAMS ((struct psymbol_allocation_list *,
#define ADD_PSYMBOL_VT_TO_LIST(NAME,NAMELENGTH,NAMESPACE,CLASS,LIST,VALUE,VT,LANGUAGE, OBJFILE) \
do { \
register struct partial_symbol *psym; \
char *buf = alloca ((NAMELENGTH) + 1); \
struct partial_symbol psymbol; \
memcpy (buf, (NAME), (NAMELENGTH)); \
buf[(NAMELENGTH)] = '\0'; \
SYMBOL_NAME (&psymbol) = bcache (buf, (NAMELENGTH) + 1, &(OBJFILE)->psymbol_cache); \
VT (&psymbol) = (VALUE); \
SYMBOL_SECTION (&psymbol) = 0; \
SYMBOL_LANGUAGE (&psymbol) = (LANGUAGE); \
PSYMBOL_NAMESPACE (&psymbol) = (NAMESPACE); \
PSYMBOL_CLASS (&psymbol) = (CLASS); \
SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, (LANGUAGE)); \
psym = bcache (&psymbol, sizeof (struct partial_symbol), &(OBJFILE)->psymbol_cache); \
if ((LIST).next >= (LIST).list + (LIST).size) \
extend_psymbol_list (&(LIST),(OBJFILE)); \
psym = (LIST).next++; \
SYMBOL_NAME (psym) = \
(char *) obstack_alloc (&objfile->psymbol_obstack, \
(NAMELENGTH) + 1); \
memcpy (SYMBOL_NAME (psym), (NAME), (NAMELENGTH)); \
SYMBOL_NAME (psym)[(NAMELENGTH)] = '\0'; \
SYMBOL_NAMESPACE (psym) = (NAMESPACE); \
SYMBOL_SECTION (psym) = 0; \
PSYMBOL_CLASS (psym) = (CLASS); \
VT (psym) = (VALUE); \
SYMBOL_LANGUAGE (psym) = (LANGUAGE); \
SYMBOL_INIT_LANGUAGE_SPECIFIC (psym, LANGUAGE); \
OBJSTAT (objfile, n_psyms++); \
extend_psymbol_list (&(LIST), (OBJFILE)); \
*(LIST).next++ = psym; \
OBJSTAT ((OBJFILE), n_psyms++); \
} while (0)
/* Add a symbol with an integer value to a psymtab. */
@ -174,8 +183,8 @@ new_symfile_objfile PARAMS ((struct objfile *, int, int));
extern struct partial_symtab *
start_psymtab_common PARAMS ((struct objfile *, struct section_offsets *,
char *, CORE_ADDR,
struct partial_symbol *,
struct partial_symbol *));
struct partial_symbol **,
struct partial_symbol **));
/* Sorting your symbols for fast lookup or alphabetical printing. */

View File

@ -63,7 +63,7 @@ static int
block_depth PARAMS ((struct block *));
static void
print_partial_symbol PARAMS ((struct partial_symbol *, int, char *, GDB_FILE *));
print_partial_symbols PARAMS ((struct partial_symbol **, int, char *, GDB_FILE *));
struct print_symbol_args {
struct symbol *symbol;
@ -152,6 +152,20 @@ free_symtab (s)
#if MAINTENANCE_CMDS
void
print_symbol_bcache_statistics ()
{
struct objfile *objfile;
immediate_quit++;
ALL_OBJFILES (objfile)
{
printf_filtered ("Cached obstack statistics for '%s':\n", objfile -> name);
print_bcache_statistics (&objfile -> psymbol_cache, "partial symbol obstack");
}
immediate_quit--;
}
void
print_objfile_statistics ()
{
@ -373,13 +387,13 @@ dump_psymtab (objfile, psymtab, outfile)
}
if (psymtab -> n_global_syms > 0)
{
print_partial_symbol (objfile -> global_psymbols.list
print_partial_symbols (objfile -> global_psymbols.list
+ psymtab -> globals_offset,
psymtab -> n_global_syms, "Global", outfile);
}
if (psymtab -> n_static_syms > 0)
{
print_partial_symbol (objfile -> static_psymbols.list
print_partial_symbols (objfile -> static_psymbols.list
+ psymtab -> statics_offset,
psymtab -> n_static_syms, "Static", outfile);
}
@ -461,7 +475,7 @@ dump_symtab (objfile, symtab, outfile)
s.depth = depth + 1;
s.outfile = outfile;
catch_errors (print_symbol, &s, "Error printing symbol:\n",
RETURN_MASK_ERROR);
RETURN_MASK_ALL);
}
}
fprintf_filtered (outfile, "\n");
@ -730,23 +744,22 @@ maintenance_print_psymbols (args, from_tty)
}
static void
print_partial_symbol (p, count, what, outfile)
struct partial_symbol *p;
print_partial_symbols (p, count, what, outfile)
struct partial_symbol **p;
int count;
char *what;
GDB_FILE *outfile;
{
fprintf_filtered (outfile, " %s partial symbols:\n", what);
while (count-- > 0)
{
fprintf_filtered (outfile, " `%s'", SYMBOL_NAME(p));
if (SYMBOL_DEMANGLED_NAME (p) != NULL)
fprintf_filtered (outfile, " `%s'", SYMBOL_NAME(*p));
if (SYMBOL_DEMANGLED_NAME (*p) != NULL)
{
fprintf_filtered (outfile, " `%s'", SYMBOL_DEMANGLED_NAME (p));
fprintf_filtered (outfile, " `%s'", SYMBOL_DEMANGLED_NAME (*p));
}
fputs_filtered (", ", outfile);
switch (SYMBOL_NAMESPACE (p))
switch (SYMBOL_NAMESPACE (*p))
{
case UNDEF_NAMESPACE:
fputs_filtered ("undefined namespace, ", outfile);
@ -764,7 +777,7 @@ print_partial_symbol (p, count, what, outfile)
fputs_filtered ("<invalid namespace>, ", outfile);
break;
}
switch (SYMBOL_CLASS (p))
switch (SYMBOL_CLASS (*p))
{
case LOC_UNDEF:
fputs_filtered ("undefined", outfile);
@ -822,7 +835,7 @@ print_partial_symbol (p, count, what, outfile)
/* FIXME-32x64: Need to use SYMBOL_VALUE_ADDRESS, etc.; this
could be 32 bits when some of the other fields in the union
are 64. */
fprintf_filtered (outfile, "0x%lx\n", SYMBOL_VALUE (p));
fprintf_filtered (outfile, "0x%lx\n", SYMBOL_VALUE (*p));
p++;
}
}
@ -901,7 +914,7 @@ maintenance_check_symtabs (ignore, from_tty)
int from_tty;
{
register struct symbol *sym;
register struct partial_symbol *psym;
register struct partial_symbol **psym;
register struct symtab *s = NULL;
register struct partial_symtab *ps;
struct blockvector *bv;
@ -920,12 +933,12 @@ maintenance_check_symtabs (ignore, from_tty)
length = ps->n_static_syms;
while (length--)
{
sym = lookup_block_symbol (b, SYMBOL_NAME (psym),
SYMBOL_NAMESPACE (psym));
sym = lookup_block_symbol (b, SYMBOL_NAME (*psym),
SYMBOL_NAMESPACE (*psym));
if (!sym)
{
printf_filtered ("Static symbol `");
puts_filtered (SYMBOL_NAME (psym));
puts_filtered (SYMBOL_NAME (*psym));
printf_filtered ("' only found in ");
puts_filtered (ps->filename);
printf_filtered (" psymtab\n");
@ -937,12 +950,12 @@ maintenance_check_symtabs (ignore, from_tty)
length = ps->n_global_syms;
while (length--)
{
sym = lookup_block_symbol (b, SYMBOL_NAME (psym),
SYMBOL_NAMESPACE (psym));
sym = lookup_block_symbol (b, SYMBOL_NAME (*psym),
SYMBOL_NAMESPACE (*psym));
if (!sym)
{
printf_filtered ("Global symbol `");
puts_filtered (SYMBOL_NAME (psym));
puts_filtered (SYMBOL_NAME (*psym));
printf_filtered ("' only found in ");
puts_filtered (ps->filename);
printf_filtered (" psymtab\n");
@ -998,7 +1011,7 @@ block_depth (block)
/* Increase the space allocated for LISTP, which is probably
global_psymbol_list or static_psymbol_list. This space will eventually
global_psymbols or static_psymbols. This space will eventually
be freed in free_objfile(). */
void
@ -1010,15 +1023,15 @@ extend_psymbol_list (listp, objfile)
if (listp->size == 0)
{
new_size = 255;
listp->list = (struct partial_symbol *)
xmmalloc (objfile -> md, new_size * sizeof (struct partial_symbol));
listp->list = (struct partial_symbol **)
xmmalloc (objfile -> md, new_size * sizeof (struct partial_symbol *));
}
else
{
new_size = listp->size * 2;
listp->list = (struct partial_symbol *)
listp->list = (struct partial_symbol **)
xmrealloc (objfile -> md, (char *) listp->list,
new_size * sizeof (struct partial_symbol));
new_size * sizeof (struct partial_symbol *));
}
/* Next assumes we only went one over. Should be good if
program works correctly */

View File

@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "obstack.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
#include "bcache.h"
/* Don't do this; it means that if some .o's are compiled with GNU C
and some are not (easy to do accidentally the way we configure

View File

@ -1933,7 +1933,7 @@ static unsigned int first_fun_line_offset;
static struct partial_symtab *xcoff_start_psymtab
PARAMS ((struct objfile *, struct section_offsets *, char *, int,
struct partial_symbol *, struct partial_symbol *));
struct partial_symbol **, struct partial_symbol **));
/* Allocate and partially fill a partial symtab. It will be
completely filled at the end of the symbol list.
@ -1949,8 +1949,8 @@ xcoff_start_psymtab (objfile, section_offsets,
struct section_offsets *section_offsets;
char *filename;
int first_symnum;
struct partial_symbol *global_syms;
struct partial_symbol *static_syms;
struct partial_symbol **global_syms;
struct partial_symbol **static_syms;
{
struct partial_symtab *result =
start_psymtab_common (objfile, section_offsets,