* gdb.texinfo (Maintenance Commands): Document "maint set dwarf2
	max-cache-age" and "maint show dwarf2 max-cache-age".
gdb/
	* Makefile.in (dwarf2read.o): Update dependencies.
	* dwarf2read.c: Include "command.h" and "gdbcmd.h".
	(struct dwarf2_per_objfile): Add all_comp_units, n_comp_units,
	and read_in_chain.
	(struct dwarf2_cu): Add read_in_chain, per_cu, last_used,
	mark, and has_form_ref_addr.
	(struct dwarf2_per_cu_data): New.
	(dwarf2_max_cache_age): New.
	(dwarf2_build_psymtabs_hard): Free cached compilation units
	after loading.  Create and manage the list of compilation units.
	Remove unnecessary NULL initialization.  Fix indentation.
	(psymtab_to_symtab_1): Initialize all of CU.
	(dwarf2_read_abbrevs): Set has_form_ref_addr.
	(find_partial_die): Use dwarf2_find_containing_comp_unit
	and load_comp_unit.
	(free_stack_comp_unit): Update comments.  Clear the per-cu
	pointer.  Handle aging.
	(dwarf2_find_containing_comp_unit, free_cached_comp_units)
	(age_cached_comp_units, free_one_cached_comp_unit)
	(dwarf2_mark, dwarf2_clear_marks, create_all_comp_units)
	(load_comp_unit, dwarf2_find_comp_unit, free_one_comp_unit)
	(set_dwarf2_cmdlist, show_dwarf2_cmdlist, set_dwarf2_cmd)
	(show_dwarf2_cmd): New.
	(_initialize_dwarf2_read): Provide "maint set dwarf2 max-cache-age"
	and "maint show dwarf2 max-cache-age".
	* gdbcmd.h (maintenance_set_cmdlist, maintenance_show_cmdlist): New
	externs.
	* maint.c (maintenance_set_cmdlist, maintenance_show_cmdlist): Make
	global.
This commit is contained in:
Daniel Jacobowitz 2004-09-20 22:26:21 +00:00
parent 987504bb93
commit ae038cb03c
7 changed files with 559 additions and 11 deletions

View File

@ -1,3 +1,35 @@
2004-09-20 Daniel Jacobowitz <dan@debian.org>
* Makefile.in (dwarf2read.o): Update dependencies.
* dwarf2read.c: Include "command.h" and "gdbcmd.h".
(struct dwarf2_per_objfile): Add all_comp_units, n_comp_units,
and read_in_chain.
(struct dwarf2_cu): Add read_in_chain, per_cu, last_used,
mark, and has_form_ref_addr.
(struct dwarf2_per_cu_data): New.
(dwarf2_max_cache_age): New.
(dwarf2_build_psymtabs_hard): Free cached compilation units
after loading. Create and manage the list of compilation units.
Remove unnecessary NULL initialization. Fix indentation.
(psymtab_to_symtab_1): Initialize all of CU.
(dwarf2_read_abbrevs): Set has_form_ref_addr.
(find_partial_die): Use dwarf2_find_containing_comp_unit
and load_comp_unit.
(free_stack_comp_unit): Update comments. Clear the per-cu
pointer. Handle aging.
(dwarf2_find_containing_comp_unit, free_cached_comp_units)
(age_cached_comp_units, free_one_cached_comp_unit)
(dwarf2_mark, dwarf2_clear_marks, create_all_comp_units)
(load_comp_unit, dwarf2_find_comp_unit, free_one_comp_unit)
(set_dwarf2_cmdlist, show_dwarf2_cmdlist, set_dwarf2_cmd)
(show_dwarf2_cmd): New.
(_initialize_dwarf2_read): Provide "maint set dwarf2 max-cache-age"
and "maint show dwarf2 max-cache-age".
* gdbcmd.h (maintenance_set_cmdlist, maintenance_show_cmdlist): New
externs.
* maint.c (maintenance_set_cmdlist, maintenance_show_cmdlist): Make
global.
2004-09-20 Jeff Johnston <jjohnstn@redhat.com>
* dwarf2read.c (typename_concat): Change prototype to accept obstack

View File

@ -1848,7 +1848,8 @@ dwarf2read.o: dwarf2read.c $(defs_h) $(bfd_h) $(symtab_h) $(gdbtypes_h) \
$(objfiles_h) $(elf_dwarf2_h) $(buildsym_h) $(demangle_h) \
$(expression_h) $(filenames_h) $(macrotab_h) $(language_h) \
$(complaints_h) $(bcache_h) $(dwarf2expr_h) $(dwarf2loc_h) \
$(cp_support_h) $(hashtab_h) $(gdb_string_h) $(gdb_assert_h)
$(cp_support_h) $(hashtab_h) $(gdb_string_h) $(gdb_assert_h) \
$(command_h) $(gdbcmd_h)
dwarfread.o: dwarfread.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(objfiles_h) \
$(elf_dwarf_h) $(buildsym_h) $(demangle_h) $(expression_h) \
$(language_h) $(complaints_h) $(gdb_string_h)

View File

@ -1,3 +1,8 @@
2004-09-20 Daniel Jacobowitz <dan@debian.org>
* gdb.texinfo (Maintenance Commands): Document "maint set dwarf2
max-cache-age" and "maint show dwarf2 max-cache-age".
2004-09-16 Eli Zaretskii <eliz@gnu.org>
* gdb.texinfo (Set Breaks): Add index entry for setting

View File

@ -19551,6 +19551,19 @@ data in a @file{gmon.out} file, be sure to move it to a safe location.
Configuring with @samp{--enable-profiling} arranges for @value{GDBN} to be
compiled with the @samp{-pg} compiler option.
@kindex maint set dwarf2 max-cache-age
@kindex maint show dwarf2 max-cache-age
@item maint set dwarf2 max-cache-age
@itemx maint show dwarf2 max-cache-age
Control the DWARF 2 compilation unit cache.
In object files with inter-compilation-unit references, such as those
produced by the GCC option @samp{-feliminate-dwarf2-dups}, the DWARF 2
reader needs to frequently refer to previously read compilation units.
This setting controls how long a compilation unit will remain in the cache
if it is not referenced. Setting it to zero disables caching, which will
slow down @value{GDBN} startup but reduce memory consumption.
@end table

View File

@ -45,6 +45,8 @@
#include "dwarf2loc.h"
#include "cp-support.h"
#include "hashtab.h"
#include "command.h"
#include "gdbcmd.h"
#include <fcntl.h>
#include "gdb_string.h"
@ -166,6 +168,18 @@ struct dwarf2_per_objfile
char *macinfo_buffer;
char *ranges_buffer;
char *loc_buffer;
/* A list of all the compilation units. This will be set if and
only if we have encountered a compilation unit with inter-CU
references. */
struct dwarf2_per_cu_data **all_comp_units;
/* The number of compilation units in ALL_COMP_UNITS. */
int n_comp_units;
/* A chain of compilation units that are currently read in, so that
they can be freed later. */
struct dwarf2_per_cu_data *read_in_chain;
};
static struct dwarf2_per_objfile *dwarf2_per_objfile;
@ -299,6 +313,25 @@ struct dwarf2_cu
unit, including partial DIEs. */
struct obstack comp_unit_obstack;
/* When multiple dwarf2_cu structures are living in memory, this field
chains them all together, so that they can be released efficiently.
We will probably also want a generation counter so that most-recently-used
compilation units are cached... */
struct dwarf2_per_cu_data *read_in_chain;
/* Backchain to our per_cu entry if the tree has been built. */
struct dwarf2_per_cu_data *per_cu;
/* How many compilation units ago was this CU last referenced? */
int last_used;
/* Mark used when releasing cached dies. */
unsigned int mark : 1;
/* This flag will be set if this compilation unit might include
inter-compilation-unit references. */
unsigned int has_form_ref_addr : 1;
/* This flag will be set if this compilation unit includes any
DW_TAG_namespace DIEs. If we know that there are explicit
DIEs for namespaces, we don't need to try to infer them
@ -306,6 +339,22 @@ struct dwarf2_cu
unsigned int has_namespace_info : 1;
};
struct dwarf2_per_cu_data
{
/* The start offset and length of this compilation unit. 2**31-1
bytes should suffice to store the length of any compilation unit
- if it doesn't, GDB will fall over anyway. */
unsigned long offset;
unsigned long length : 31;
/* Flag indicating this compilation unit will be read in before
any of the current compilation units are processed. */
unsigned long queued : 1;
/* Set iff currently read in. */
struct dwarf2_cu *cu;
};
/* The line number information for a compilation unit (found in the
.debug_line section) begins with a "statement program header",
which contains the following information. */
@ -585,6 +634,13 @@ struct field_info
int nfnfields;
};
/* Loaded secondary compilation units are kept in memory until they
have not been referenced for the processing of this many
compilation units. Set this to zero to disable caching. Cache
sizes of up to at least twenty will improve startup time for
typical inter-CU-reference binaries, at an obvious memory cost. */
static int dwarf2_max_cache_age = 5;
/* Various complaints about symbol reading that don't abort the process */
static void
@ -965,6 +1021,26 @@ static hashval_t partial_die_hash (const void *item);
static int partial_die_eq (const void *item_lhs, const void *item_rhs);
static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
(unsigned long offset, struct objfile *objfile);
static struct dwarf2_per_cu_data *dwarf2_find_comp_unit
(unsigned long offset, struct objfile *objfile);
static void free_one_comp_unit (void *);
static void free_cached_comp_units (void *);
static void age_cached_comp_units (void);
static void free_one_cached_comp_unit (void *);
static void create_all_comp_units (struct objfile *);
static void dwarf2_mark (struct dwarf2_cu *);
static void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
/* Try to locate the sections we need for DWARF 2 debugging
information and return true if we have enough to do something. */
@ -1291,10 +1367,15 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
char *beg_of_comp_unit;
struct partial_die_info comp_unit_die;
struct partial_symtab *pst;
struct cleanup *back_to;
CORE_ADDR lowpc, highpc, baseaddr;
info_ptr = dwarf2_per_objfile->info_buffer;
/* Any cached compilation units will be linked by the per-objfile
read_in_chain. Make sure to free them when we're done. */
back_to = make_cleanup (free_cached_comp_units, NULL);
/* Since the objects we're extracting from .debug_info vary in
length, only the individual functions to extract them (like
read_comp_unit_head and load_partial_die) can really know whether
@ -1335,12 +1416,13 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
cu.list_in_scope = &file_symbols;
cu.partial_dies = NULL;
/* Read the abbrevs for this compilation unit into a table */
dwarf2_read_abbrevs (abfd, &cu);
make_cleanup (dwarf2_free_abbrev_table, &cu);
if (cu.has_form_ref_addr && dwarf2_per_objfile->all_comp_units == NULL)
create_all_comp_units (objfile);
/* Read the compilation unit die */
abbrev = peek_die_abbrev (info_ptr, &bytes_read, &cu);
info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read,
@ -1356,8 +1438,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
objfile->global_psymbols.next,
objfile->static_psymbols.next);
if (comp_unit_die.dirname)
pst->dirname = xstrdup (comp_unit_die.dirname);
if (comp_unit_die.dirname)
pst->dirname = xstrdup (comp_unit_die.dirname);
pst->read_symtab_private = (char *)
obstack_alloc (&objfile->objfile_obstack, sizeof (struct dwarf2_pinfo));
@ -1367,6 +1449,32 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
/* Store the function that reads in the rest of the symbol table */
pst->read_symtab = dwarf2_psymtab_to_symtab;
if (dwarf2_per_objfile->all_comp_units != NULL)
{
struct dwarf2_per_cu_data *per_cu;
per_cu = dwarf2_find_comp_unit (cu.header.offset, objfile);
/* If this compilation unit was already read in, free the
cached copy in order to read it in again. This is
necessary because we skipped some symbols when we first
read in the compilation unit (see load_partial_dies).
This problem could be avoided, but the benefit is
unclear. */
if (per_cu->cu != NULL)
free_one_cached_comp_unit (per_cu->cu);
cu.per_cu = per_cu;
/* Note that this is a pointer to our stack frame, being
added to a global data structure. It will be cleaned up
in free_stack_comp_unit when we finish with this
compilation unit. */
per_cu->cu = &cu;
}
else
cu.per_cu = NULL;
/* Check if comp unit has_children.
If so, read the rest of the partial symbols from this comp unit.
If not, there's no more debug_info for this comp unit. */
@ -1420,6 +1528,122 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
do_cleanups (back_to_inner);
}
do_cleanups (back_to);
}
/* Load the DIEs for a secondary CU into memory. */
static void
load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile)
{
bfd *abfd = objfile->obfd;
char *info_ptr, *beg_of_comp_unit;
struct partial_die_info comp_unit_die;
struct dwarf2_cu *cu;
struct abbrev_info *abbrev;
unsigned int bytes_read;
struct cleanup *back_to;
info_ptr = dwarf2_per_objfile->info_buffer + this_cu->offset;
beg_of_comp_unit = info_ptr;
cu = xmalloc (sizeof (struct dwarf2_cu));
memset (cu, 0, sizeof (struct dwarf2_cu));
obstack_init (&cu->comp_unit_obstack);
cu->objfile = objfile;
info_ptr = partial_read_comp_unit_head (&cu->header, info_ptr, abfd);
/* Complete the cu_header. */
cu->header.offset = beg_of_comp_unit - dwarf2_per_objfile->info_buffer;
cu->header.first_die_ptr = info_ptr;
cu->header.cu_head_ptr = beg_of_comp_unit;
/* Read the abbrevs for this compilation unit into a table. */
dwarf2_read_abbrevs (abfd, cu);
back_to = make_cleanup (dwarf2_free_abbrev_table, cu);
/* Read the compilation unit die. */
abbrev = peek_die_abbrev (info_ptr, &bytes_read, cu);
info_ptr = read_partial_die (&comp_unit_die, abbrev, bytes_read,
abfd, info_ptr, cu);
/* Set the language we're debugging. */
set_cu_language (comp_unit_die.language, cu);
/* Link this compilation unit into the compilation unit tree. */
this_cu->cu = cu;
cu->per_cu = this_cu;
/* Check if comp unit has_children.
If so, read the rest of the partial symbols from this comp unit.
If not, there's no more debug_info for this comp unit. */
if (comp_unit_die.has_children)
load_partial_dies (abfd, info_ptr, 0, cu);
do_cleanups (back_to);
}
/* Create a list of all compilation units in OBJFILE. We do this only
if an inter-comp-unit reference is found; presumably if there is one,
there will be many, and one will occur early in the .debug_info section.
So there's no point in building this list incrementally. */
static void
create_all_comp_units (struct objfile *objfile)
{
int n_allocated;
int n_comp_units;
struct dwarf2_per_cu_data **all_comp_units;
char *info_ptr = dwarf2_per_objfile->info_buffer;
n_comp_units = 0;
n_allocated = 10;
all_comp_units = xmalloc (n_allocated
* sizeof (struct dwarf2_per_cu_data *));
while (info_ptr < dwarf2_per_objfile->info_buffer + dwarf2_per_objfile->info_size)
{
struct comp_unit_head cu_header;
char *beg_of_comp_unit;
struct dwarf2_per_cu_data *this_cu;
unsigned long offset;
int bytes_read;
offset = info_ptr - dwarf2_per_objfile->info_buffer;
/* Read just enough information to find out where the next
compilation unit is. */
cu_header.length = read_initial_length (objfile->obfd, info_ptr,
&cu_header, &bytes_read);
/* Save the compilation unit for later lookup. */
this_cu = obstack_alloc (&objfile->objfile_obstack,
sizeof (struct dwarf2_per_cu_data));
memset (this_cu, 0, sizeof (*this_cu));
this_cu->offset = offset;
this_cu->length = cu_header.length + cu_header.initial_length_size;
if (n_comp_units == n_allocated)
{
n_allocated *= 2;
all_comp_units = xrealloc (all_comp_units,
n_allocated
* sizeof (struct dwarf2_per_cu_data *));
}
all_comp_units[n_comp_units++] = this_cu;
info_ptr = info_ptr + this_cu->length;
}
dwarf2_per_objfile->all_comp_units
= obstack_alloc (&objfile->objfile_obstack,
n_comp_units * sizeof (struct dwarf2_per_cu_data *));
memcpy (dwarf2_per_objfile->all_comp_units, all_comp_units,
n_comp_units * sizeof (struct dwarf2_per_cu_data *));
xfree (all_comp_units);
dwarf2_per_objfile->n_comp_units = n_comp_units;
}
/* Process all loaded DIEs for compilation unit CU, starting at FIRST_DIE.
@ -2144,6 +2368,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
/* We're in the global namespace. */
processing_current_prefix = "";
memset (&cu, 0, sizeof (struct dwarf2_cu));
obstack_init (&cu.comp_unit_obstack);
back_to = make_cleanup (free_stack_comp_unit, &cu);
@ -4614,6 +4839,17 @@ dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
= xrealloc (cur_attrs, (allocated_attrs
* sizeof (struct attr_abbrev)));
}
/* Record whether this compilation unit might have
inter-compilation-unit references. If we don't know what form
this attribute will have, then it might potentially be a
DW_FORM_ref_addr, so we conservatively expect inter-CU
references. */
if (abbrev_form == DW_FORM_ref_addr
|| abbrev_form == DW_FORM_indirect)
cu->has_form_ref_addr = 1;
cur_attrs[cur_abbrev->num_attrs].name = abbrev_name;
cur_attrs[cur_abbrev->num_attrs++].form = abbrev_form;
abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
@ -5066,8 +5302,25 @@ find_partial_die (unsigned long offset, struct dwarf2_cu *cu,
return find_partial_die_in_comp_unit (offset, cu);
}
internal_error (__FILE__, __LINE__,
"unsupported inter-compilation-unit reference");
per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
/* If this offset isn't pointing into a known compilation unit,
the debug information is probably corrupted. */
if (per_cu == NULL)
error ("Dwarf Error: could not find partial DIE containing "
"offset 0x%lx [in module %s]",
(long) offset, bfd_get_filename (cu->objfile->obfd));
if (per_cu->cu == NULL)
{
load_comp_unit (per_cu, cu->objfile);
per_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
dwarf2_per_objfile->read_in_chain = per_cu;
}
per_cu->cu->last_used = 0;
*target_cu = per_cu->cu;
return find_partial_die_in_comp_unit (offset, per_cu->cu);
}
/* Adjust PART_DIE before generating a symbol for it. This function
@ -8812,9 +9065,81 @@ dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
}
}
/* Locate the compilation unit from CU's objfile which contains the
DIE at OFFSET. Returns NULL on failure. */
static struct dwarf2_per_cu_data *
dwarf2_find_containing_comp_unit (unsigned long offset,
struct objfile *objfile)
{
struct dwarf2_per_cu_data *this_cu;
int low, high;
if (dwarf2_per_objfile->all_comp_units == NULL)
error ("Dwarf Error: offset 0x%lx points outside this "
"compilation unit [in module %s]",
offset, bfd_get_filename (objfile->obfd));
low = 0;
high = dwarf2_per_objfile->n_comp_units - 1;
while (high > low)
{
int mid = low + (high - low) / 2;
if (dwarf2_per_objfile->all_comp_units[mid]->offset >= offset)
high = mid;
else
low = mid + 1;
}
gdb_assert (low == high);
if (dwarf2_per_objfile->all_comp_units[low]->offset > offset)
{
gdb_assert (low > 0);
gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset <= offset);
return dwarf2_per_objfile->all_comp_units[low-1];
}
else
{
this_cu = dwarf2_per_objfile->all_comp_units[low];
if (low == dwarf2_per_objfile->n_comp_units - 1
&& offset >= this_cu->offset + this_cu->length)
error ("invalid dwarf2 offset %ld", offset);
gdb_assert (offset < this_cu->offset + this_cu->length);
return this_cu;
}
}
static struct dwarf2_per_cu_data *
dwarf2_find_comp_unit (unsigned long offset, struct objfile *objfile)
{
struct dwarf2_per_cu_data *this_cu;
this_cu = dwarf2_find_containing_comp_unit (offset, objfile);
if (this_cu->offset != offset)
error ("no compilation unit with offset %ld\n", offset);
return this_cu;
}
/* Release one cached compilation unit, CU. We unlink it from the tree
of compilation units, but we don't remove it from the read_in_chain;
the caller is responsible for that. */
static void
free_one_comp_unit (void *data)
{
struct dwarf2_cu *cu = data;
if (cu->per_cu != NULL)
cu->per_cu->cu = NULL;
cu->per_cu = NULL;
obstack_free (&cu->comp_unit_obstack, NULL);
xfree (cu);
}
/* This cleanup function is passed the address of a dwarf2_cu on the stack
when we're finished with it. We can't free the pointer itself, but
release any associated storage.
when we're finished with it. We can't free the pointer itself, but be
sure to unlink it from the cache. Also release any associated storage
and perform cache maintenance.
Only used during partial symbol parsing. */
@ -8825,6 +9150,127 @@ free_stack_comp_unit (void *data)
obstack_free (&cu->comp_unit_obstack, NULL);
cu->partial_dies = NULL;
if (cu->per_cu != NULL)
{
/* This compilation unit is on the stack in our caller, so we
should not xfree it. Just unlink it. */
cu->per_cu->cu = NULL;
cu->per_cu = NULL;
/* If we had a per-cu pointer, then we may have other compilation
units loaded, so age them now. */
age_cached_comp_units ();
}
}
/* Free all cached compilation units. */
static void
free_cached_comp_units (void *data)
{
struct dwarf2_per_cu_data *per_cu, **last_chain;
per_cu = dwarf2_per_objfile->read_in_chain;
last_chain = &dwarf2_per_objfile->read_in_chain;
while (per_cu != NULL)
{
struct dwarf2_per_cu_data *next_cu;
next_cu = per_cu->cu->read_in_chain;
free_one_comp_unit (per_cu->cu);
*last_chain = next_cu;
per_cu = next_cu;
}
}
/* Increase the age counter on each cached compilation unit, and free
any that are too old. */
static void
age_cached_comp_units (void)
{
struct dwarf2_per_cu_data *per_cu, **last_chain;
dwarf2_clear_marks (dwarf2_per_objfile->read_in_chain);
per_cu = dwarf2_per_objfile->read_in_chain;
while (per_cu != NULL)
{
per_cu->cu->last_used ++;
if (per_cu->cu->last_used <= dwarf2_max_cache_age)
dwarf2_mark (per_cu->cu);
per_cu = per_cu->cu->read_in_chain;
}
per_cu = dwarf2_per_objfile->read_in_chain;
last_chain = &dwarf2_per_objfile->read_in_chain;
while (per_cu != NULL)
{
struct dwarf2_per_cu_data *next_cu;
next_cu = per_cu->cu->read_in_chain;
if (!per_cu->cu->mark)
{
free_one_comp_unit (per_cu->cu);
*last_chain = next_cu;
}
else
last_chain = &per_cu->cu->read_in_chain;
per_cu = next_cu;
}
}
/* Remove a single compilation unit from the cache. */
static void
free_one_cached_comp_unit (void *target_cu)
{
struct dwarf2_per_cu_data *per_cu, **last_chain;
per_cu = dwarf2_per_objfile->read_in_chain;
last_chain = &dwarf2_per_objfile->read_in_chain;
while (per_cu != NULL)
{
struct dwarf2_per_cu_data *next_cu;
next_cu = per_cu->cu->read_in_chain;
if (per_cu->cu == target_cu)
{
free_one_comp_unit (per_cu->cu);
*last_chain = next_cu;
break;
}
else
last_chain = &per_cu->cu->read_in_chain;
per_cu = next_cu;
}
}
/* Set the mark field in CU and in every other compilation unit in the
cache that we must keep because we are keeping CU. */
static void
dwarf2_mark (struct dwarf2_cu *cu)
{
if (cu->mark)
return;
cu->mark = 1;
}
static void
dwarf2_clear_marks (struct dwarf2_per_cu_data *per_cu)
{
while (per_cu)
{
per_cu->cu->mark = 0;
per_cu = per_cu->cu->read_in_chain;
}
}
/* Allocation function for the libiberty hash table which uses an
@ -8870,10 +9316,53 @@ partial_die_eq (const void *item_lhs, const void *item_rhs)
return part_die_lhs->offset == part_die_rhs->offset;
}
static struct cmd_list_element *set_dwarf2_cmdlist;
static struct cmd_list_element *show_dwarf2_cmdlist;
static void
set_dwarf2_cmd (char *args, int from_tty)
{
help_list (set_dwarf2_cmdlist, "maintenance set dwarf2 ", -1, gdb_stdout);
}
static void
show_dwarf2_cmd (char *args, int from_tty)
{
cmd_show_list (show_dwarf2_cmdlist, from_tty, "");
}
void _initialize_dwarf2_read (void);
void
_initialize_dwarf2_read (void)
{
dwarf2_objfile_data_key = register_objfile_data ();
add_prefix_cmd ("dwarf2", class_maintenance, set_dwarf2_cmd,
"Set DWARF 2 specific variables.\n"
"Configure DWARF 2 variables such as the cache size",
&set_dwarf2_cmdlist, "maintenance set dwarf2 ",
0/*allow-unknown*/, &maintenance_set_cmdlist);
add_prefix_cmd ("dwarf2", class_maintenance, show_dwarf2_cmd,
"Show DWARF 2 specific variables\n"
"Show DWARF 2 variables such as the cache size",
&show_dwarf2_cmdlist, "maintenance show dwarf2 ",
0/*allow-unknown*/, &maintenance_show_cmdlist);
add_setshow_zinteger_cmd ("max-cache-age", class_obscure,
&dwarf2_max_cache_age,
"Set the upper bound on the age of cached "
"dwarf2 compilation units.",
"Show the upper bound on the age of cached "
"dwarf2 compilation units.",
"A higher limit means that cached "
"compilation units will be stored\n"
"in memory longer, and more total memory will "
"be used. Zero disables\n"
"caching, which can slow down startup.",
"The upper bound on the age of cached "
"dwarf2 compilation units is %d.",
NULL, NULL, &set_dwarf2_cmdlist,
&show_dwarf2_cmdlist);
}

View File

@ -98,6 +98,14 @@ extern struct cmd_list_element *maintenanceinfolist;
extern struct cmd_list_element *maintenanceprintlist;
/* Chain containing all defined "maintenance set" subcommands. */
extern struct cmd_list_element *maintenance_set_cmdlist;
/* Chain containing all defined "maintenance show" subcommands. */
extern struct cmd_list_element *maintenance_show_cmdlist;
extern struct cmd_list_element *setprintlist;
extern struct cmd_list_element *showprintlist;

View File

@ -609,8 +609,8 @@ maintenance_do_deprecate (char *text, int deprecate)
/* Maintenance set/show framework. */
static struct cmd_list_element *maintenance_set_cmdlist;
static struct cmd_list_element *maintenance_show_cmdlist;
struct cmd_list_element *maintenance_set_cmdlist;
struct cmd_list_element *maintenance_show_cmdlist;
static void
maintenance_set_cmd (char *args, int from_tty)