aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2004-02-23 21:09:12 +0000
committerDaniel Jacobowitz <drow@false.org>2004-02-23 21:09:12 +0000
commitfd0c5d01112170c4a3cc69b18b7af266ee7eb92b (patch)
tree12648c44c3df51cf52dbb50bea7a21ce36d3ef21
parent5257c72d769eae184421f3314cc7dbdbaca6d9b7 (diff)
downloadfsf-binutils-gdb-fd0c5d01112170c4a3cc69b18b7af266ee7eb92b.zip
fsf-binutils-gdb-fd0c5d01112170c4a3cc69b18b7af266ee7eb92b.tar.gz
fsf-binutils-gdb-fd0c5d01112170c4a3cc69b18b7af266ee7eb92b.tar.bz2
* dwarf2read.c (struct dwarf2_per_objfile_data): Add comment
for cu_tree. Add read_in_chain. (age_cached_comp_units): New function. (clear_per_cu_pointer): Clear the pointer ourself. Call age_cached_comp_units. (free_cached_comp_units, free_one_cached_comp_unit): Update call to free_comp_units_worker. (dwarf2_build_psymtabs_hard): Use the per-objfile read_in_chain. (find_partial_die): Likewise. (free_comp_units_worker): Don't try to clear the per_cu pointer for the list head. Remove now-unused argument. Use the per-objfile read_in_chain.
-rw-r--r--gdb/ChangeLog.intercu15
-rw-r--r--gdb/dwarf2read.c69
2 files changed, 58 insertions, 26 deletions
diff --git a/gdb/ChangeLog.intercu b/gdb/ChangeLog.intercu
index c9d743c..2f6a75c 100644
--- a/gdb/ChangeLog.intercu
+++ b/gdb/ChangeLog.intercu
@@ -1,5 +1,20 @@
2004-02-23 Daniel Jacobowitz <drow@mvista.com>
+ * dwarf2read.c (struct dwarf2_per_objfile_data): Add comment
+ for cu_tree. Add read_in_chain.
+ (age_cached_comp_units): New function.
+ (clear_per_cu_pointer): Clear the pointer ourself. Call
+ age_cached_comp_units.
+ (free_cached_comp_units, free_one_cached_comp_unit): Update call to
+ free_comp_units_worker.
+ (dwarf2_build_psymtabs_hard): Use the per-objfile read_in_chain.
+ (find_partial_die): Likewise.
+ (free_comp_units_worker): Don't try to clear the per_cu pointer
+ for the list head. Remove now-unused argument. Use the per-objfile
+ read_in_chain.
+
+2004-02-23 Daniel Jacobowitz <drow@mvista.com>
+
* dwarf2read.c (dwarf2_read_abbrevs): Return 1 for DW_FORM_indirect
also.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 7eb4fbb..f86a16d 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -158,7 +158,14 @@ struct dwarf2_per_objfile_data
char *dwarf_ranges_buffer;
char *dwarf_loc_buffer;
+ /* A tree of all the compilation units. Each member is a pointer
+ to a struct dwarf2_cu. This will be set if and only if we have
+ encountered a compilation unit with inter-CU references. */
splay_tree cu_tree;
+
+ /* 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;
};
#define dwarf_info_size dwarf2_per_objfile->dwarf_info_size
@@ -961,6 +968,8 @@ static void clear_per_cu_pointer (void *);
static void free_cached_comp_units (void *);
+static void age_cached_comp_units (void *);
+
static void free_one_cached_comp_unit (struct dwarf2_cu *, struct dwarf2_cu *);
static void set_die_type (struct die_info *, struct type *,
@@ -1311,12 +1320,9 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
obstack_init (&dwarf2_tmp_obstack);
back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
- /* read_in_chain, unlike every other field in the dwarf2_cu object,
- is live across the loop. The function clear_per_cu_pointer will
- free any allocated compilation units that have not been used in
- several psymtabs. Others will remain on the list. */
- cu.read_in_chain = NULL;
- make_cleanup (free_cached_comp_units, &cu);
+ /* Any cached compilation units will be linked by the per-objfile
+ read_in_chain. Make sure to free them when we're done. */
+ make_cleanup (free_cached_comp_units, NULL);
/* Since the objects we're extracting from dwarf_info_buffer vary in
length, only the individual functions to extract them (like
@@ -1353,6 +1359,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
cu.partial_dies = NULL;
+ cu.read_in_chain = NULL;
+
/* Read the abbrevs for this compilation unit into a table */
saw_ref_addr = dwarf2_read_abbrevs (abfd, &cu);
back_to_inner = make_cleanup (dwarf2_empty_abbrev_table, &cu);
@@ -5155,8 +5163,8 @@ find_partial_die (unsigned long offset, struct dwarf2_cu *cu,
if (per_cu->cu == NULL)
{
load_comp_unit (per_cu, cu->objfile);
- per_cu->cu->read_in_chain = cu->read_in_chain;
- cu->read_in_chain = per_cu;
+ 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;
@@ -8890,18 +8898,19 @@ dwarf2_find_containing_comp_unit (unsigned long offset,
return this_cu;
}
+/* Helper function for cleaning up the compilation unit cache. Walk
+ this objfile's read_in_chain. If AGING, increase the age counter
+ on each compilation unit, and free any that are too old. Otherwise,
+ if TARGET_CU, free only that compilation unit, removing it from the
+ chain. Otherwise free all compilation units. */
+
static void
-free_comp_units_worker (struct dwarf2_cu *cu, int aging,
- struct dwarf2_cu *target_cu)
+free_comp_units_worker (struct dwarf2_cu *target_cu, int aging)
{
- struct dwarf2_per_cu_data *this_cu, *per_cu, **last_chain;
-
- this_cu = cu->per_cu;
- if (this_cu == NULL && target_cu == NULL)
- return;
+ struct dwarf2_per_cu_data *per_cu, **last_chain;
- per_cu = cu->read_in_chain;
- last_chain = &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;
@@ -8925,32 +8934,40 @@ free_comp_units_worker (struct dwarf2_cu *cu, int aging,
per_cu = next_cu;
}
+}
- /* This compilation unit is on the stack in dwarf2_build_psymtabs_hard,
- so we should not xfree it. Just unlink it. */
- if (target_cu == NULL)
+static void
+clear_per_cu_pointer (void *data)
+{
+ struct dwarf2_cu *cu = data;
+
+ if (cu->per_cu != NULL)
{
+ age_cached_comp_units (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;
- this_cu->cu = NULL;
}
}
static void
-clear_per_cu_pointer (void *data)
+free_cached_comp_units (void *data)
{
- free_comp_units_worker (data, 1, NULL);
+ free_comp_units_worker (NULL, 0);
}
static void
-free_cached_comp_units (void *data)
+age_cached_comp_units (void *data)
{
- free_comp_units_worker (data, 0, NULL);
+ free_comp_units_worker (NULL, 1);
}
static void
free_one_cached_comp_unit (struct dwarf2_cu *cu, struct dwarf2_cu *target_cu)
{
- free_comp_units_worker (cu, 0, target_cu);
+ free_comp_units_worker (target_cu, 0);
}
struct dwarf2_offset_and_type