* 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> Fri Feb 16 10:02:34 1996 Fred Fish <fnf@cygnus.com>
* dwarfread.c (free_utypes): New function. * dwarfread.c (free_utypes): New function.

View File

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

View File

@ -3,6 +3,12 @@
*** Changes since GDB-4.15: *** 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 * New native configurations
Windows 95, Windows NT i[345]86-*-win32 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 static struct partial_symtab *hpread_start_psymtab
PARAMS ((struct objfile *, struct section_offsets *, char *, CORE_ADDR, int, 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 static struct partial_symtab *hpread_end_psymtab
PARAMS ((struct partial_symtab *, char **, int, int, CORE_ADDR, PARAMS ((struct partial_symtab *, char **, int, int, CORE_ADDR,
@ -827,8 +827,8 @@ hpread_start_psymtab (objfile, section_offsets,
char *filename; char *filename;
CORE_ADDR textlow; CORE_ADDR textlow;
int ldsymoff; int ldsymoff;
struct partial_symbol *global_syms; struct partial_symbol **global_syms;
struct partial_symbol *static_syms; struct partial_symbol **static_syms;
{ {
struct partial_symtab *result = struct partial_symtab *result =
start_psymtab_common (objfile, section_offsets, start_psymtab_common (objfile, section_offsets,

View File

@ -249,7 +249,10 @@ maintenance_print_statistics (args, from_tty)
char *args; char *args;
int from_tty; int from_tty;
{ {
int temp;
print_objfile_statistics (); print_objfile_statistics ();
print_symbol_bcache_statistics ();
} }
/* The "maintenance print" command is defined as a prefix, with allow_unknown /* 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 -> md = md;
objfile -> mmfd = fd; objfile -> mmfd = fd;
/* Update pointers to functions to *our* copies */ /* 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_chunkfun (&objfile -> psymbol_obstack, xmmalloc);
obstack_freefun (&objfile -> psymbol_obstack, mfree); obstack_freefun (&objfile -> psymbol_obstack, mfree);
obstack_chunkfun (&objfile -> symbol_obstack, xmmalloc); obstack_chunkfun (&objfile -> symbol_obstack, xmmalloc);
@ -186,6 +188,9 @@ allocate_objfile (abfd, mapped)
objfile -> mmfd = fd; objfile -> mmfd = fd;
objfile -> flags |= OBJF_MAPPED; objfile -> flags |= OBJF_MAPPED;
mmalloc_setkey (objfile -> md, 0, objfile); 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, obstack_specify_allocation_with_arg (&objfile -> psymbol_obstack,
0, 0, xmmalloc, mfree, 0, 0, xmmalloc, mfree,
objfile -> md); objfile -> md);
@ -228,6 +233,8 @@ allocate_objfile (abfd, mapped)
objfile = (struct objfile *) xmalloc (sizeof (struct objfile)); objfile = (struct objfile *) xmalloc (sizeof (struct objfile));
memset (objfile, 0, sizeof (struct objfile)); memset (objfile, 0, sizeof (struct objfile));
objfile -> md = NULL; objfile -> md = NULL;
obstack_specify_allocation (&objfile -> psymbol_cache.cache, 0, 0,
xmalloc, free);
obstack_specify_allocation (&objfile -> psymbol_obstack, 0, 0, xmalloc, obstack_specify_allocation (&objfile -> psymbol_obstack, 0, 0, xmalloc,
free); free);
obstack_specify_allocation (&objfile -> symbol_obstack, 0, 0, xmalloc, obstack_specify_allocation (&objfile -> symbol_obstack, 0, 0, xmalloc,
@ -433,6 +440,7 @@ free_objfile (objfile)
if (objfile->static_psymbols.list) if (objfile->static_psymbols.list)
mfree (objfile->md, objfile->static_psymbols.list); mfree (objfile->md, objfile->static_psymbols.list);
/* Free the obstacks for non-reusable objfiles */ /* Free the obstacks for non-reusable objfiles */
obstack_free (&objfile -> psymbol_cache.cache, 0);
obstack_free (&objfile -> psymbol_obstack, 0); obstack_free (&objfile -> psymbol_obstack, 0);
obstack_free (&objfile -> symbol_obstack, 0); obstack_free (&objfile -> symbol_obstack, 0);
obstack_free (&objfile -> type_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; for (psym = objfile->global_psymbols.list;
psym < objfile->global_psymbols.next; psym < objfile->global_psymbols.next;
psym++) psym++)
if (SYMBOL_SECTION (psym) >= 0) if (SYMBOL_SECTION (*psym) >= 0)
SYMBOL_VALUE_ADDRESS (psym) += ANOFFSET (delta, SYMBOL_SECTION (psym)); SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta, SYMBOL_SECTION (*psym));
for (psym = objfile->static_psymbols.list; for (psym = objfile->static_psymbols.list;
psym < objfile->static_psymbols.next; psym < objfile->static_psymbols.next;
psym++) psym++)
if (SYMBOL_SECTION (psym) >= 0) if (SYMBOL_SECTION (*psym) >= 0)
SYMBOL_VALUE_ADDRESS (psym) += ANOFFSET (delta, SYMBOL_SECTION (psym)); 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 symbol_obstack; /* Full symbols */
struct obstack type_obstack; /* Types */ 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 /* Vectors of all partial symbols read in from file. The actual data
is stored in the psymbol_obstack. */ 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 * static struct partial_symtab *
os9k_start_psymtab PARAMS ((struct objfile *, struct section_offsets *, char *, os9k_start_psymtab PARAMS ((struct objfile *, struct section_offsets *, char *,
CORE_ADDR, int, int, struct partial_symbol *, CORE_ADDR, int, int, struct partial_symbol **,
struct partial_symbol *)); struct partial_symbol **));
static struct partial_symtab * static struct partial_symtab *
os9k_end_psymtab PARAMS ((struct partial_symtab *, char **, int, int, CORE_ADDR, 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; CORE_ADDR textlow;
int ldsymoff; int ldsymoff;
int ldsymcnt; int ldsymcnt;
struct partial_symbol *global_syms; struct partial_symbol **global_syms;
struct partial_symbol *static_syms; struct partial_symbol **static_syms;
{ {
struct partial_symtab *result = struct partial_symtab *result =
start_psymtab_common(objfile, section_offsets, start_psymtab_common(objfile, section_offsets,

View File

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

View File

@ -148,9 +148,9 @@ LOCAL FUNCTION
DESCRIPTION DESCRIPTION
Given pointer to two partial symbol table entries, compare Given pointers to pointers to two partial symbol table entries,
them by name and return -N, 0, or +N (ala strcmp). Typically compare them by name and return -N, 0, or +N (ala strcmp).
used by sorting routines like qsort(). Typically used by sorting routines like qsort().
NOTES NOTES
@ -167,8 +167,8 @@ compare_psymbols (s1p, s2p)
const PTR s1p; const PTR s1p;
const PTR s2p; const PTR s2p;
{ {
register char *st1 = SYMBOL_NAME ((struct partial_symbol *) s1p); register char *st1 = SYMBOL_NAME (*(struct partial_symbol **) s1p);
register char *st2 = SYMBOL_NAME ((struct partial_symbol *) s2p); register char *st2 = SYMBOL_NAME (*(struct partial_symbol **) s2p);
if ((st1[0] - st2[0]) || !st1[0]) 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 */ /* Sort the global list; don't sort the static list */
qsort (pst -> objfile -> global_psymbols.list + pst -> globals_offset, 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); compare_psymbols);
} }
@ -1192,6 +1192,7 @@ reread_symbols ()
objfile->static_psymbols.size = 0; objfile->static_psymbols.size = 0;
/* Free the obstacks for non-reusable objfiles */ /* Free the obstacks for non-reusable objfiles */
obstack_free (&objfile -> psymbol_cache.cache, 0);
obstack_free (&objfile -> psymbol_obstack, 0); obstack_free (&objfile -> psymbol_obstack, 0);
obstack_free (&objfile -> symbol_obstack, 0); obstack_free (&objfile -> symbol_obstack, 0);
obstack_free (&objfile -> type_obstack, 0); obstack_free (&objfile -> type_obstack, 0);
@ -1211,6 +1212,8 @@ reread_symbols ()
objfile -> md = NULL; objfile -> md = NULL;
/* obstack_specify_allocation also initializes the obstack so /* obstack_specify_allocation also initializes the obstack so
it is empty. */ it is empty. */
obstack_specify_allocation (&objfile -> psymbol_cache.cache, 0, 0,
xmalloc, free);
obstack_specify_allocation (&objfile -> psymbol_obstack, 0, 0, obstack_specify_allocation (&objfile -> psymbol_obstack, 0, 0,
xmalloc, free); xmalloc, free);
obstack_specify_allocation (&objfile -> symbol_obstack, 0, 0, obstack_specify_allocation (&objfile -> symbol_obstack, 0, 0,
@ -1616,8 +1619,8 @@ start_psymtab_common (objfile, section_offsets,
struct section_offsets *section_offsets; struct section_offsets *section_offsets;
char *filename; char *filename;
CORE_ADDR textlow; CORE_ADDR textlow;
struct partial_symbol *global_syms; struct partial_symbol **global_syms;
struct partial_symbol *static_syms; struct partial_symbol **static_syms;
{ {
struct partial_symtab *psymtab; struct partial_symtab *psymtab;
@ -1651,24 +1654,29 @@ add_psymbol_to_list (name, namelength, namespace, class, list, val, language,
struct objfile *objfile; struct objfile *objfile;
{ {
register struct partial_symbol *psym; 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) if (list->next >= list->list + list->size)
{ {
extend_psymbol_list (list,objfile); extend_psymbol_list (list, objfile);
} }
psym = list->next++; *list->next++ = psym;
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);
OBJSTAT (objfile, n_psyms++); OBJSTAT (objfile, n_psyms++);
} }
@ -1687,24 +1695,29 @@ add_psymbol_addr_to_list (name, namelength, namespace, class, list, val,
struct objfile *objfile; struct objfile *objfile;
{ {
register struct partial_symbol *psym; 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) if (list->next >= list->list + list->size)
{ {
extend_psymbol_list (list,objfile); extend_psymbol_list (list, objfile);
} }
psym = list->next++; *list->next++ = psym;
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);
OBJSTAT (objfile, n_psyms++); OBJSTAT (objfile, n_psyms++);
} }
@ -1735,13 +1748,13 @@ init_psymbol_list (objfile, total_symbols)
objfile -> global_psymbols.size = total_symbols / 10; objfile -> global_psymbols.size = total_symbols / 10;
objfile -> static_psymbols.size = total_symbols / 10; objfile -> static_psymbols.size = total_symbols / 10;
objfile -> global_psymbols.next = 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 xmmalloc (objfile -> md, objfile -> global_psymbols.size
* sizeof (struct partial_symbol)); * sizeof (struct partial_symbol *));
objfile -> static_psymbols.next = 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 xmmalloc (objfile -> md, objfile -> static_psymbols.size
* sizeof (struct partial_symbol)); * sizeof (struct partial_symbol *));
} }
void 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". */ /* 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 psymbol_allocation_list {
struct partial_symbol *list; struct partial_symbol **list; /* Pointer to first partial symbol pointer*/
struct partial_symbol *next; struct partial_symbol **next; /* Pointer to next avail storage for pointer */
int size; int size; /* Number of symbols */
}; };
/* Structure to keep track of symbol reading functions for various /* 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) \ #define ADD_PSYMBOL_VT_TO_LIST(NAME,NAMELENGTH,NAMESPACE,CLASS,LIST,VALUE,VT,LANGUAGE, OBJFILE) \
do { \ do { \
register struct partial_symbol *psym; \ 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) \ if ((LIST).next >= (LIST).list + (LIST).size) \
extend_psymbol_list (&(LIST),(OBJFILE)); \ extend_psymbol_list (&(LIST), (OBJFILE)); \
psym = (LIST).next++; \ *(LIST).next++ = psym; \
SYMBOL_NAME (psym) = \ OBJSTAT ((OBJFILE), n_psyms++); \
(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++); \
} while (0) } while (0)
/* Add a symbol with an integer value to a psymtab. */ /* 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 * extern struct partial_symtab *
start_psymtab_common PARAMS ((struct objfile *, struct section_offsets *, start_psymtab_common PARAMS ((struct objfile *, struct section_offsets *,
char *, CORE_ADDR, char *, CORE_ADDR,
struct partial_symbol *, struct partial_symbol **,
struct partial_symbol *)); struct partial_symbol **));
/* Sorting your symbols for fast lookup or alphabetical printing. */ /* Sorting your symbols for fast lookup or alphabetical printing. */

View File

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

View File

@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "obstack.h" #include "obstack.h"
#define obstack_chunk_alloc xmalloc #define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free #define obstack_chunk_free free
#include "bcache.h"
/* Don't do this; it means that if some .o's are compiled with GNU C /* 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 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 static struct partial_symtab *xcoff_start_psymtab
PARAMS ((struct objfile *, struct section_offsets *, char *, int, 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 /* Allocate and partially fill a partial symtab. It will be
completely filled at the end of the symbol list. completely filled at the end of the symbol list.
@ -1949,8 +1949,8 @@ xcoff_start_psymtab (objfile, section_offsets,
struct section_offsets *section_offsets; struct section_offsets *section_offsets;
char *filename; char *filename;
int first_symnum; int first_symnum;
struct partial_symbol *global_syms; struct partial_symbol **global_syms;
struct partial_symbol *static_syms; struct partial_symbol **static_syms;
{ {
struct partial_symtab *result = struct partial_symtab *result =
start_psymtab_common (objfile, section_offsets, start_psymtab_common (objfile, section_offsets,