This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[intercu] Memory management update


This moves the read_in_chain from the first compilation unit, to the
per-objfile data.  Now we don't have something "on" the chain that
lives on someone's stack frame.  This will simplify full CU processing.

Committed to the intercu branch.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

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.

Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.135.2.28
diff -u -p -r1.135.2.28 dwarf2read.c
--- dwarf2read.c	23 Feb 2004 20:09:15 -0000	1.135.2.28
+++ dwarf2read.c	23 Feb 2004 21:05:46 -0000
@@ -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 objfi
   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 objfi
 
       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, 
   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 (unsign
   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
 
       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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]