mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-05-31 10:09:16 +08:00
* 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:
@ -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.
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
6
gdb/NEWS
6
gdb/NEWS
@ -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
188
gdb/bcache.c
Normal 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
46
gdb/bcache.h
Normal 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 */
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -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. */
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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. */
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
Reference in New Issue
Block a user