This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[intercu] Fix lazy tree building
- From: Daniel Jacobowitz <drow at false dot org>
- To: gdb-patches at sources dot redhat dot com
- Date: Mon, 23 Feb 2004 15:05:03 -0500
- Subject: [intercu] Fix lazy tree building
As I mentioned a patch or two ago. We can tell during dwarf2_read_abbrevs
if this compilation unit will use DW_FORM_ref_addr, without having to walk
all DIEs; we can just walk the abbrevs.
Committed to the intercu branch.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
2004-02-23 Daniel Jacobowitz <drow@mvista.com>
* dwarf2read.c (dwarf2_read_abbrevs): Return 1 iff we saw any
DW_FORM_ref_addr tags.
(create_comp_unit_tree): Add prototype. Take an objfile instead
of a compilation unit.
(dwarf2_build_psymtabs_hard): Build the compilation unit tree
as soon as we find an inter-CU reference. Update call to
create_comp_unit_tree.
(dwarf2_find_containing_comp_unit): Don't create the tree here.
(psymtab_to_symtab_1): Update to support no tree having been built.
(set_die_type): Likewise.
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.135.2.26
diff -u -p -r1.135.2.26 dwarf2read.c
--- dwarf2read.c 23 Feb 2004 19:33:47 -0000 1.135.2.26
+++ dwarf2read.c 23 Feb 2004 19:54:57 -0000
@@ -673,7 +673,7 @@ static void psymtab_to_symtab_1 (struct
char *dwarf2_read_section (struct objfile *, asection *);
-static void dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu);
+static int dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu);
static void dwarf2_empty_abbrev_table (void *);
@@ -969,6 +969,8 @@ static void set_die_type (struct die_inf
static void reset_die_and_siblings_types (struct die_info *,
struct dwarf2_cu *);
+static splay_tree create_comp_unit_tree (struct objfile *);
+
/* Allocation function for the libiberty splay tree which uses an obstack. */
static void *
splay_tree_obstack_allocate (int size, void *data)
@@ -1335,6 +1337,7 @@ dwarf2_build_psymtabs_hard (struct objfi
struct abbrev_info *abbrev;
unsigned int bytes_read;
struct dwarf2_per_cu_data *this_cu;
+ int saw_ref_addr;
beg_of_comp_unit = info_ptr;
@@ -1351,9 +1354,12 @@ dwarf2_build_psymtabs_hard (struct objfi
cu.partial_dies = NULL;
/* Read the abbrevs for this compilation unit into a table */
- dwarf2_read_abbrevs (abfd, &cu);
+ saw_ref_addr = dwarf2_read_abbrevs (abfd, &cu);
back_to_inner = make_cleanup (dwarf2_empty_abbrev_table, &cu);
+ if (saw_ref_addr && cu_tree == NULL)
+ cu_tree = create_comp_unit_tree (objfile);
+
/* Read the compilation unit die */
abbrev = peek_die_abbrev (info_ptr, &bytes_read, &cu);
info_ptr = load_partial_die (&comp_unit_die, abbrev, bytes_read,
@@ -1378,9 +1384,6 @@ dwarf2_build_psymtabs_hard (struct objfi
/* Store the function that reads in the rest of the symbol table */
pst->read_symtab = dwarf2_psymtab_to_symtab;
- if (cu_tree == NULL)
- cu_tree = dwarf2_per_objfile->cu_tree;
-
if (cu_tree != NULL)
{
splay_tree_node node;
@@ -1542,10 +1545,9 @@ load_comp_unit (struct dwarf2_per_cu_dat
So there's no point in building this tree incrementally. */
static splay_tree
-create_comp_unit_tree (struct dwarf2_cu *cu)
+create_comp_unit_tree (struct objfile *objfile)
{
splay_tree cu_tree;
- struct objfile *objfile = cu->objfile;
char *info_ptr = dwarf_info_buffer;
/* Initialize the compilation unit tree. */
@@ -1579,12 +1581,6 @@ create_comp_unit_tree (struct dwarf2_cu
this_cu->length = cu_header.length;
splay_tree_insert (cu_tree, this_cu->offset, (splay_tree_value) this_cu);
- if (this_cu->offset == cu->header.offset)
- {
- this_cu->cu = cu;
- cu->per_cu = this_cu;
- }
-
info_ptr = beg_of_comp_unit + cu_header.length
+ cu_header.initial_length_size;
}
@@ -2280,15 +2276,27 @@ psymtab_to_symtab_1 (struct partial_symt
so much trouble to keep lazy during partial symbol reading. If this
proves to be unavoidable then we may want to strip out the lazy code
during partial symbol reading also. */
- cu.per_cu = dwarf2_find_containing_comp_unit (offset + 1, &cu);
- /* As in partial symbol table building, this leaks a pointer to our stack
- frame into a global data structure. Be sure to clear it before we
- return. */
- cu.per_cu->cu = &cu;
- make_cleanup (clear_per_cu_pointer, &cu);
- cu.read_in_chain = NULL;
+ if (dwarf2_per_objfile->cu_tree == NULL)
+ cu.per_cu = NULL;
+ else
+ {
+ splay_tree_node node;
+ struct dwarf2_per_cu_data *per_cu;
+
+ node = splay_tree_lookup (dwarf2_per_objfile->cu_tree, cu.header.offset);
+ gdb_assert (node != NULL);
+ cu.per_cu = (struct dwarf2_per_cu_data *) node->value;
- cu.per_cu->psymtab = pst;
+ /* As in partial symbol table building, this leaks a pointer to
+ our stack frame into a global data structure. Be sure to
+ clear it before we return. */
+ cu.per_cu->cu = &cu;
+ make_cleanup (clear_per_cu_pointer, &cu);
+
+ cu.per_cu->psymtab = pst;
+ }
+
+ cu.read_in_chain = NULL;
cu.list_in_scope = &file_symbols;
@@ -4652,7 +4660,7 @@ dwarf2_read_section (struct objfile *obj
dies from a section we read in all abbreviations and install them
in a hash table. */
-static void
+static int
dwarf2_read_abbrevs (bfd *abfd, struct dwarf2_cu *cu)
{
struct comp_unit_head *cu_header = &cu->header;
@@ -4662,6 +4670,7 @@ dwarf2_read_abbrevs (bfd *abfd, struct d
unsigned int abbrev_form, hash_number;
struct attr_abbrev *cur_attrs;
unsigned int allocated_attrs;
+ int saw_ref_addr = 0;
/* Initialize dwarf2 abbrevs */
obstack_init (&cu->abbrev_obstack);
@@ -4701,6 +4710,10 @@ dwarf2_read_abbrevs (bfd *abfd, struct d
= xrealloc (cur_attrs, (allocated_attrs
* sizeof (struct attr_abbrev)));
}
+
+ if (abbrev_form == DW_FORM_ref_addr)
+ saw_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);
@@ -4736,6 +4749,8 @@ dwarf2_read_abbrevs (bfd *abfd, struct d
}
xfree (cur_attrs);
+
+ return saw_ref_addr;
}
/* Empty the abbrev table for a new compilation unit. */
@@ -8859,8 +8874,7 @@ dwarf2_find_containing_comp_unit (unsign
splay_tree_node node;
cu_tree = dwarf2_per_objfile->cu_tree;
- if (cu_tree == NULL)
- cu_tree = create_comp_unit_tree (cu);
+ gdb_assert (cu_tree != NULL);
node = splay_tree_predecessor (cu_tree, offset);
gdb_assert (node != NULL);
@@ -8965,6 +8979,9 @@ set_die_type (struct die_info *die, stru
struct dwarf2_offset_and_type **slot, ofs;
die->type = type;
+
+ if (cu->per_cu == NULL)
+ return;
type_hash = PST_PRIVATE (cu->per_cu->psymtab)->type_hash;
if (type_hash == NULL)