]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
* dwarf2read.c (struct dwarf2_per_objfile): Replace cu_tree
authorDaniel Jacobowitz <drow@false.org>
Sat, 7 Aug 2004 18:34:06 +0000 (18:34 +0000)
committerDaniel Jacobowitz <drow@false.org>
Sat, 7 Aug 2004 18:34:06 +0000 (18:34 +0000)
with all_comp_units and n_comp_units.
(dwarf2_find_containing_comp_unit): Take an objfile argument
instead of a dwarf2_cu.  Search all_comp_units.
(dwarf2_find_comp_unit): New function.
(create_all_comp_units): Renamed from create_comp_unit_tree.
Create a list instead of a splay tree.
(dwarf2_build_psymtabs_hard): Call create_comp_unit_tree
and dwarf2_find_comp_unit.
(psymtab_to_symtab_1): Check all_comp_units.  Use
dwarf2_find_comp_unit.
(find_partial_die, read_full_die, follow_die_ref): Update calls
to dwarf2_find_containing_comp_unit.

gdb/ChangeLog.intercu
gdb/dwarf2read.c

index 2ce2da29ae3c6bb7defdace8fe3d134d82b3b8a1..5f136e5fef0247f8d3f5e02635302f962574c344 100644 (file)
@@ -1,3 +1,19 @@
+2004-08-07  Daniel Jacobowitz  <dan@debian.org>
+
+       * dwarf2read.c (struct dwarf2_per_objfile): Replace cu_tree
+       with all_comp_units and n_comp_units.
+       (dwarf2_find_containing_comp_unit): Take an objfile argument
+       instead of a dwarf2_cu.  Search all_comp_units.
+       (dwarf2_find_comp_unit): New function.
+       (create_all_comp_units): Renamed from create_comp_unit_tree.
+       Create a list instead of a splay tree.
+       (dwarf2_build_psymtabs_hard): Call create_comp_unit_tree
+       and dwarf2_find_comp_unit.
+       (psymtab_to_symtab_1): Check all_comp_units.  Use
+       dwarf2_find_comp_unit.
+       (find_partial_die, read_full_die, follow_die_ref): Update calls
+       to dwarf2_find_containing_comp_unit.
+
 2004-04-19  Daniel Jacobowitz  <drow@mvista.com>
 
        * dwarf2read.c (free_comp_units_worker): Remove incorrect aging.
index 4b3f97b5b88f923e24852a7a96702fcf52e8b048..0d51c13fb70caa105852fb976b9948ad73a386ca 100644 (file)
@@ -170,10 +170,13 @@ struct dwarf2_per_objfile
   char *ranges_buffer;
   char *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 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.  */
@@ -1010,7 +1013,10 @@ static char *skip_one_die (char *info_ptr, struct abbrev_info *abbrev,
                           struct dwarf2_cu *cu);
 
 static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
-  (unsigned long offset, struct dwarf2_cu *cu);
+  (unsigned long offset, struct objfile *objfile);
+
+static struct dwarf2_per_cu_data *dwarf2_find_comp_unit
+  (unsigned long offset, struct objfile *objfile);
 
 static struct partial_symtab *dwarf2_find_comp_unit_psymtab
   (unsigned int offset, struct objfile *objfile);
@@ -1031,7 +1037,7 @@ static void set_die_type (struct die_info *, struct type *,
 static void reset_die_and_siblings_types (struct die_info *,
                                          struct dwarf2_cu *);
 
-static splay_tree create_comp_unit_tree (struct objfile *);
+static void create_all_comp_units (struct objfile *);
 
 static struct dwarf2_cu *load_full_comp_unit (struct partial_symtab *,
                                              struct dwarf2_per_cu_data *);
@@ -1327,7 +1333,6 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
   struct partial_symtab *pst;
   struct cleanup *back_to;
   CORE_ADDR lowpc, highpc, baseaddr;
-  splay_tree cu_tree = NULL;
 
   info_ptr = dwarf2_per_objfile->info_buffer;
 
@@ -1383,8 +1388,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
       dwarf2_read_abbrevs (abfd, &cu);
       make_cleanup (dwarf2_free_abbrev_table, &cu);
 
-      if (cu.has_form_ref_addr && cu_tree == NULL)
-       cu_tree = create_comp_unit_tree (objfile);
+      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);
@@ -1410,14 +1415,11 @@ 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 (cu_tree != NULL)
+      if (dwarf2_per_objfile->all_comp_units != NULL)
        {
-         splay_tree_node node;
          struct dwarf2_per_cu_data *per_cu;
 
-         node = splay_tree_lookup (cu_tree, cu.header.offset);
-         gdb_assert (node != NULL);
-         per_cu = (struct dwarf2_per_cu_data *) node->value;
+         per_cu = dwarf2_find_comp_unit (cu.header.offset, objfile);
 
          /* If we were already read in, free ourselves to read in again.
             Yes, this is pointless duplication.  Fixing this will provide
@@ -1542,25 +1544,24 @@ load_comp_unit (struct dwarf2_per_cu_data *this_cu, struct objfile *objfile)
   do_cleanups (back_to);
 }
 
-/* Create a tree of all compilation units in OBJFILE.  We do this only
+/* 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 tree incrementally.  */
+   So there's no point in building this list incrementally.  */
 
-static splay_tree
-create_comp_unit_tree (struct objfile *objfile)
+static void
+create_all_comp_units (struct objfile *objfile)
 {
-  splay_tree cu_tree;
+  int n_allocated;
+  int n_comp_units;
+  struct dwarf2_per_cu_data **all_comp_units;
   char *info_ptr = dwarf2_per_objfile->info_buffer;
 
-  /* Initialize the compilation unit tree.  */
-  cu_tree = splay_tree_new_with_allocator (splay_tree_compare_ints,
-                                          NULL, NULL,
-                                          splay_tree_obstack_allocate,
-                                          dummy_obstack_deallocate,
-                                          &objfile->objfile_obstack);
-  dwarf2_per_objfile->cu_tree = cu_tree;
-
+  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;
@@ -1582,12 +1583,26 @@ create_comp_unit_tree (struct objfile *objfile)
       memset (this_cu, 0, sizeof (*this_cu));
       this_cu->offset = offset;
       this_cu->length = cu_header.length + cu_header.initial_length_size;
-      splay_tree_insert (cu_tree, this_cu->offset, (splay_tree_value) this_cu);
+
+      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;
     }
 
-  return cu_tree;
+  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.
@@ -2358,7 +2373,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
 {
   struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
 
-  if (dwarf2_per_objfile->cu_tree == NULL)
+  if (dwarf2_per_objfile->all_comp_units == NULL)
     {
       struct dwarf2_cu *cu;
       cu = load_full_comp_unit (pst, NULL);
@@ -2367,14 +2382,11 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
     }
   else
     {
-      splay_tree_node node;
       struct dwarf2_per_cu_data *per_cu;
       unsigned long offset;
 
       offset = DWARF_INFO_OFFSET (pst);
-      node = splay_tree_lookup (dwarf2_per_objfile->cu_tree, offset);
-      gdb_assert (node != NULL);
-      per_cu = (struct dwarf2_per_cu_data *) node->value;
+      per_cu = dwarf2_find_comp_unit (offset, pst->objfile);
 
       per_cu->psymtab = pst;
 
@@ -5329,7 +5341,7 @@ find_partial_die (unsigned long offset, struct dwarf2_cu *cu,
       return find_partial_die_in_comp_unit (offset, cu);
     }
 
-  per_cu = dwarf2_find_containing_comp_unit (offset, cu);
+  per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
   gdb_assert (per_cu != NULL);
 
   if (per_cu->cu == NULL)
@@ -5446,7 +5458,7 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
        {
          struct dwarf2_per_cu_data *per_cu;
          per_cu = dwarf2_find_containing_comp_unit (DW_ADDR (&die->attrs[i]),
-                                                    cu);
+                                                    cu->objfile);
 
          dwarf2_add_dependence (cu, per_cu);
 
@@ -8328,7 +8340,7 @@ follow_die_ref (struct attribute *attr, struct dwarf2_cu *cu,
     {
       struct dwarf2_per_cu_data *per_cu;
       per_cu = dwarf2_find_containing_comp_unit (DW_ADDR (attr),
-                                                cu);
+                                                cu->objfile);
       *spec_cu = per_cu->cu;
     }
   else
@@ -9071,30 +9083,52 @@ 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.
-
-   We assume that OFFSET is not the start of the compilation unit header
-   (it can be the compilation unit DIE, though, which comes after the
-   header).  */
+   DIE at OFFSET.  Returns NULL on failure.  */
 
 static struct dwarf2_per_cu_data *
 dwarf2_find_containing_comp_unit (unsigned long offset,
-                                 struct dwarf2_cu *cu)
+                                 struct objfile *objfile)
 {
-  struct objfile *objfile = cu->objfile;
   struct dwarf2_per_cu_data *this_cu;
-  splay_tree cu_tree;
-  splay_tree_node node;
+  int low, high;
 
-  cu_tree = dwarf2_per_objfile->cu_tree;
-  gdb_assert (cu_tree != NULL);
-  
-  node = splay_tree_predecessor (cu_tree, offset);
-  gdb_assert (node != NULL);
+  gdb_assert (dwarf2_per_objfile->all_comp_units != NULL);
+
+  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;
+    }
+}
 
-  this_cu = (struct dwarf2_per_cu_data *) node->value;
-  gdb_assert (offset >= this_cu->offset);
-  gdb_assert (offset < this_cu->offset + this_cu->length);
+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;
 }