[13/20] Change how reprocessing is done

Message ID 20200328192208.11324-14-tom@tromey.com
State New
Headers show
Series
  • Make DWARF attribute references safe
Related show

Commit Message

Tom Tromey March 28, 2020, 7:22 p.m.
Currently gdb keeps a vector of attributes that require reprocessing.
However, now that there is a reprocessing flag in the attribute, we
can remove the vector and instead simply loop over attributes a second
time.  Normally there are not many attributes, so this should be
reasonably cheap.

gdb/ChangeLog
2020-03-28  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.c (skip_one_die): Update.
	(read_full_die_1): Change how reprocessing is done.
	(partial_die_info::read): Update.
	(read_attribute_value): Remove need_reprocess parameter.
	(read_attribute): Likewise.
	* dwarf2/attribute.h (struct attribute) <reprocessing_p>: New
	method.
---
 gdb/ChangeLog          | 10 +++++++++
 gdb/dwarf2/attribute.h |  6 ++++++
 gdb/dwarf2/read.c      | 48 +++++++++++++++++++-----------------------
 3 files changed, 38 insertions(+), 26 deletions(-)

-- 
2.17.2

Comments

Simon Marchi March 30, 2020, 3:46 p.m. | #1
On 2020-03-28 3:22 p.m., Tom Tromey wrote:
> Currently gdb keeps a vector of attributes that require reprocessing.

> However, now that there is a reprocessing flag in the attribute, we

> can remove the vector and instead simply loop over attributes a second

> time.  Normally there are not many attributes, so this should be

> reasonably cheap.


That sounds reasonable, it simplifies the code.

> 

> gdb/ChangeLog

> 2020-03-28  Tom Tromey  <tom@tromey.com>

> 

> 	* dwarf2/read.c (skip_one_die): Update.

> 	(read_full_die_1): Change how reprocessing is done.

> 	(partial_die_info::read): Update.

> 	(read_attribute_value): Remove need_reprocess parameter.

> 	(read_attribute): Likewise.

> 	* dwarf2/attribute.h (struct attribute) <reprocessing_p>: New

> 	method.

> ---

>  gdb/ChangeLog          | 10 +++++++++

>  gdb/dwarf2/attribute.h |  6 ++++++

>  gdb/dwarf2/read.c      | 48 +++++++++++++++++++-----------------------

>  3 files changed, 38 insertions(+), 26 deletions(-)

> 

> diff --git a/gdb/dwarf2/attribute.h b/gdb/dwarf2/attribute.h

> index 972beef9825..9b387e5df05 100644

> --- a/gdb/dwarf2/attribute.h

> +++ b/gdb/dwarf2/attribute.h

> @@ -214,6 +214,12 @@ struct attribute

>      requires_reprocessing = 0;

>    }

>  

> +  /* True if this attribute requires reprocessing.  */

> +  bool reprocessing_p () const

> +  {

> +    return requires_reprocessing;

> +  }


Nitpicking on names again: the method name sounds like we inquire whether
the attribute is currently reprocessing (as if it was a lengthy operation).

So I'd name it requires_reprocessing_p.  Or just requires_reprocessing (I still
find those _p suffixes for predicates odd).

Simon
Tom Tromey April 4, 2020, 2:14 p.m. | #2
>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:


>> +  /* True if this attribute requires reprocessing.  */

>> +  bool reprocessing_p () const

>> +  {

>> +    return requires_reprocessing;

>> +  }


Simon> Nitpicking on names again: the method name sounds like we inquire whether
Simon> the attribute is currently reprocessing (as if it was a lengthy operation).

Simon> So I'd name it requires_reprocessing_p.  Or just requires_reprocessing (I still
Simon> find those _p suffixes for predicates odd).

Sounds good, I used requires_reprocessing_p.

Tom

Patch

diff --git a/gdb/dwarf2/attribute.h b/gdb/dwarf2/attribute.h
index 972beef9825..9b387e5df05 100644
--- a/gdb/dwarf2/attribute.h
+++ b/gdb/dwarf2/attribute.h
@@ -214,6 +214,12 @@  struct attribute
     requires_reprocessing = 0;
   }
 
+  /* True if this attribute requires reprocessing.  */
+  bool reprocessing_p () const
+  {
+    return requires_reprocessing;
+  }
+
 
   ENUM_BITFIELD(dwarf_attribute) name : 15;
 
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index b010c9c3b01..d3897ac2198 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1192,7 +1192,7 @@  static const struct cu_partial_die_info find_partial_die (sect_offset, int,
 
 static const gdb_byte *read_attribute (const struct die_reader_specs *,
 				       struct attribute *, struct attr_abbrev *,
-				       const gdb_byte *, bool *need_reprocess);
+				       const gdb_byte *);
 
 static void read_attribute_reprocess (const struct die_reader_specs *reader,
 				      struct attribute *attr);
@@ -8464,9 +8464,7 @@  skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
       /* The only abbrev we care about is DW_AT_sibling.  */
       if (abbrev->attrs[i].name == DW_AT_sibling)
 	{
-	  bool ignored;
-	  read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr,
-			  &ignored);
+	  read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr);
 	  if (attr.form == DW_FORM_ref_addr)
 	    complaint (_("ignoring absolute DW_AT_sibling"));
 	  else
@@ -17484,15 +17482,13 @@  read_full_die_1 (const struct die_reader_specs *reader,
      attributes.  */
   die->num_attrs = abbrev->num_attrs;
 
-  std::vector<int> indexes_that_need_reprocess;
+  bool any_need_reprocess = false;
   for (i = 0; i < abbrev->num_attrs; ++i)
     {
-      bool need_reprocess;
-      info_ptr =
-        read_attribute (reader, &die->attrs[i], &abbrev->attrs[i],
-			info_ptr, &need_reprocess);
-      if (need_reprocess)
-        indexes_that_need_reprocess.push_back (i);
+      info_ptr = read_attribute (reader, &die->attrs[i], &abbrev->attrs[i],
+				 info_ptr);
+      if (die->attrs[i].reprocessing_p ())
+	any_need_reprocess = true;
     }
 
   struct attribute *attr = die->attr (DW_AT_str_offsets_base);
@@ -17502,8 +17498,14 @@  read_full_die_1 (const struct die_reader_specs *reader,
   auto maybe_addr_base = die->addr_base ();
   if (maybe_addr_base.has_value ())
     cu->addr_base = *maybe_addr_base;
-  for (int index : indexes_that_need_reprocess)
-    read_attribute_reprocess (reader, &die->attrs[index]);
+  if (any_need_reprocess)
+    {
+      for (i = 0; i < abbrev->num_attrs; ++i)
+	{
+	  if (die->attrs[i].reprocessing_p ())
+	    read_attribute_reprocess (reader, &die->attrs[i]);
+	}
+    }
   *diep = die;
   return info_ptr;
 }
@@ -17857,13 +17859,12 @@  partial_die_info::read (const struct die_reader_specs *reader,
   std::vector<struct attribute> attr_vec (abbrev.num_attrs);
   for (i = 0; i < abbrev.num_attrs; ++i)
     {
-      bool need_reprocess;
       info_ptr = read_attribute (reader, &attr_vec[i], &abbrev.attrs[i],
-				 info_ptr, &need_reprocess);
+				 info_ptr);
       /* String and address offsets that need to do the reprocessing have
          already been read at this point, so there is no need to wait until
 	 the loop terminates to do the reprocessing.  */
-      if (need_reprocess)
+      if (attr_vec[i].reprocessing_p ())
 	read_attribute_reprocess (reader, &attr_vec[i]);
       attribute &attr = attr_vec[i];
       /* Store the data if it is of an attribute we want to keep in a
@@ -18342,8 +18343,7 @@  read_attribute_reprocess (const struct die_reader_specs *reader,
 static const gdb_byte *
 read_attribute_value (const struct die_reader_specs *reader,
 		      struct attribute *attr, unsigned form,
-		      LONGEST implicit_const, const gdb_byte *info_ptr,
-		      bool *need_reprocess)
+		      LONGEST implicit_const, const gdb_byte *info_ptr)
 {
   struct dwarf2_cu *cu = reader->cu;
   struct dwarf2_per_objfile *dwarf2_per_objfile
@@ -18354,7 +18354,6 @@  read_attribute_value (const struct die_reader_specs *reader,
   struct comp_unit_head *cu_header = &cu->header;
   unsigned int bytes_read;
   struct dwarf_block *blk;
-  *need_reprocess = false;
 
   attr->form = (enum dwarf_form) form;
   switch (form)
@@ -18528,14 +18527,13 @@  read_attribute_value (const struct die_reader_specs *reader,
 	  info_ptr += bytes_read;
 	}
       info_ptr = read_attribute_value (reader, attr, form, implicit_const,
-				       info_ptr, need_reprocess);
+				       info_ptr);
       break;
     case DW_FORM_implicit_const:
       attr->set_signed (implicit_const);
       break;
     case DW_FORM_addrx:
     case DW_FORM_GNU_addr_index:
-      *need_reprocess = true;
       attr->set_unsigned_reprocess (read_unsigned_leb128 (abfd, info_ptr,
 							  &bytes_read));
       info_ptr += bytes_read;
@@ -18573,9 +18571,8 @@  read_attribute_value (const struct die_reader_specs *reader,
 	    str_index = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
 	    info_ptr += bytes_read;
 	  }
-	*need_reprocess = true;
 	attr->set_unsigned_reprocess (str_index);
-	}
+      }
       break;
     default:
       error (_("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]"),
@@ -18611,14 +18608,13 @@  read_attribute_value (const struct die_reader_specs *reader,
 static const gdb_byte *
 read_attribute (const struct die_reader_specs *reader,
 		struct attribute *attr, struct attr_abbrev *abbrev,
-		const gdb_byte *info_ptr, bool *need_reprocess)
+		const gdb_byte *info_ptr)
 {
   attr->name = abbrev->name;
   attr->string_is_canonical = 0;
   attr->requires_reprocessing = 0;
   return read_attribute_value (reader, attr, abbrev->form,
-			       abbrev->implicit_const, info_ptr,
-			       need_reprocess);
+			       abbrev->implicit_const, info_ptr);
 }
 
 /* Return pointer to string at .debug_str offset STR_OFFSET.  */