Micro-optimize abbrev reading and storage
authorTom Tromey <tom@tromey.com>
Sat, 6 Mar 2021 16:16:59 +0000 (09:16 -0700)
committerTom Tromey <tom@tromey.com>
Sat, 6 Mar 2021 16:17:28 +0000 (09:17 -0700)
Currently, and abbrev_info points to a separately allocated array of
attr_abbrev objects.  This array is constructed in a temporary vector,
then copied to the abbrev table's obstack.

This patch changes abbrev_info to use the struct hack to store the
objects directly, and changes abbrev_table::read to avoid an extra
copy when allocating, using the "growing objects" capability of
obstacks.

This saves a bit of space, and also perhaps a little time.

2021-03-06  Tom Tromey  <tom@tromey.com>

* dwarf2/read.c (read_attribute): Make 'abbrev' const.
* dwarf2/abbrev.c (abbrev_table::alloc_abbrev): Remove.
(abbrev_table::read): Update.
* dwarf2/abbrev.h (struct attr_abbrev): Move earlier.
(struct abbrev_info): Reformat.
<attrs>: Now an array.
(struct abbrev_table) <alloc_abbrev>: Remove.

gdb/ChangeLog
gdb/dwarf2/abbrev.c
gdb/dwarf2/abbrev.h
gdb/dwarf2/read.c

index ef9e2d8a13dd9497cc02d835d3ad66dccac0995e..91b7a68894f712a7691f29f7bdbe53659acd1c81 100644 (file)
@@ -1,3 +1,13 @@
+2021-03-06  Tom Tromey  <tom@tromey.com>
+
+       * dwarf2/read.c (read_attribute): Make 'abbrev' const.
+       * dwarf2/abbrev.c (abbrev_table::alloc_abbrev): Remove.
+       (abbrev_table::read): Update.
+       * dwarf2/abbrev.h (struct attr_abbrev): Move earlier.
+       (struct abbrev_info): Reformat.
+       <attrs>: Now an array.
+       (struct abbrev_table) <alloc_abbrev>: Remove.
+
 2021-03-06  Weimin Pan  <weimin.pan@oracle.com>
 
        * ctfread.c (ctf_psymtab_add_enums): New function.
index 6219c13a94b4097a29ad08e76225bd29eb9cebb0..9ece708a1ac0fd80df7992fa2a5baf84dcba678b 100644 (file)
@@ -65,19 +65,6 @@ abbrev_table::abbrev_table (sect_offset off)
 {
 }
 
-/* Allocate space for a struct abbrev_info object in ABBREV_TABLE.  */
-
-struct abbrev_info *
-abbrev_table::alloc_abbrev ()
-{
-  struct abbrev_info *abbrev;
-
-  abbrev = XOBNEW (&m_abbrev_obstack, struct abbrev_info);
-  memset (abbrev, 0, sizeof (struct abbrev_info));
-
-  return abbrev;
-}
-
 /* Add an abbreviation to the table.  */
 
 void
@@ -97,11 +84,10 @@ abbrev_table::read (struct dwarf2_section_info *section,
   bfd *abfd = section->get_bfd_owner ();
   const gdb_byte *abbrev_ptr;
   struct abbrev_info *cur_abbrev;
-  unsigned int abbrev_number, bytes_read, abbrev_name;
-  unsigned int abbrev_form;
-  std::vector<struct attr_abbrev> cur_attrs;
+  unsigned int abbrev_number, bytes_read;
 
   abbrev_table_up abbrev_table (new struct abbrev_table (sect_off));
+  struct obstack *obstack = &abbrev_table->m_abbrev_obstack;
 
   /* Caller must ensure this.  */
   gdb_assert (section->readin);
@@ -112,56 +98,51 @@ abbrev_table::read (struct dwarf2_section_info *section,
   /* Loop until we reach an abbrev number of 0.  */
   while (abbrev_number)
     {
-      cur_attrs.clear ();
-      cur_abbrev = abbrev_table->alloc_abbrev ();
+      /* Start without any attrs.  */
+      obstack_blank (obstack, offsetof (abbrev_info, attrs));
+      cur_abbrev = (struct abbrev_info *) obstack_base (obstack);
 
-      /* read in abbrev header */
+      /* Read in abbrev header.  */
       cur_abbrev->number = abbrev_number;
       cur_abbrev->tag
-       = (enum dwarf_tag) read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+       = (enum dwarf_tag) read_unsigned_leb128 (abfd, abbrev_ptr,
+                                                &bytes_read);
       abbrev_ptr += bytes_read;
       cur_abbrev->has_children = read_1_byte (abfd, abbrev_ptr);
       abbrev_ptr += 1;
 
-      /* now read in declarations */
+      /* Now read in declarations.  */
+      int num_attrs = 0;
       for (;;)
        {
-         LONGEST implicit_const;
+         struct attr_abbrev cur_attr;
 
-         abbrev_name = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+         cur_attr.name
+           = (enum dwarf_attribute) read_unsigned_leb128 (abfd, abbrev_ptr,
+                                                          &bytes_read);
          abbrev_ptr += bytes_read;
-         abbrev_form = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
+         cur_attr.form
+           = (enum dwarf_form) read_unsigned_leb128 (abfd, abbrev_ptr,
+                                                     &bytes_read);
          abbrev_ptr += bytes_read;
-         if (abbrev_form == DW_FORM_implicit_const)
+         if (cur_attr.form == DW_FORM_implicit_const)
            {
-             implicit_const = read_signed_leb128 (abfd, abbrev_ptr,
-                                                  &bytes_read);
+             cur_attr.implicit_const = read_signed_leb128 (abfd, abbrev_ptr,
+                                                           &bytes_read);
              abbrev_ptr += bytes_read;
            }
          else
-           {
-             /* Initialize it due to a false compiler warning.  */
-             implicit_const = -1;
-           }
+           cur_attr.implicit_const = -1;
 
-         if (abbrev_name == 0)
+         if (cur_attr.name == 0)
            break;
 
-         cur_attrs.emplace_back ();
-         struct attr_abbrev &cur_attr = cur_attrs.back ();
-         cur_attr.name = (enum dwarf_attribute) abbrev_name;
-         cur_attr.form = (enum dwarf_form) abbrev_form;
-         cur_attr.implicit_const = implicit_const;
+         ++num_attrs;
+         obstack_grow (obstack, &cur_attr, sizeof (cur_attr));
        }
 
-      cur_abbrev->num_attrs = cur_attrs.size ();
-      cur_abbrev->attrs =
-       XOBNEWVEC (&abbrev_table->m_abbrev_obstack, struct attr_abbrev,
-                  cur_abbrev->num_attrs);
-      if (!cur_attrs.empty ())
-       memcpy (cur_abbrev->attrs, cur_attrs.data (),
-               cur_abbrev->num_attrs * sizeof (struct attr_abbrev));
-
+      cur_abbrev = (struct abbrev_info *) obstack_finish (obstack);
+      cur_abbrev->num_attrs = num_attrs;
       abbrev_table->add_abbrev (cur_abbrev);
 
       /* Get next abbreviation.
index 8018f49cf08a4af061135eab1974b482d97a4646..e1d8b80619b48efeed5201a7838662a29c6ce30f 100644 (file)
 
 #include "hashtab.h"
 
-/* This data structure holds the information of an abbrev.  */
-struct abbrev_info
-  {
-    unsigned int number;       /* number identifying abbrev */
-    enum dwarf_tag tag;                /* dwarf tag */
-    unsigned short has_children;               /* boolean */
-    unsigned short num_attrs;  /* number of attributes */
-    struct attr_abbrev *attrs; /* an array of attribute descriptions */
-  };
-
 struct attr_abbrev
-  {
-    ENUM_BITFIELD(dwarf_attribute) name : 16;
-    ENUM_BITFIELD(dwarf_form) form : 16;
+{
+  ENUM_BITFIELD(dwarf_attribute) name : 16;
+  ENUM_BITFIELD(dwarf_form) form : 16;
 
-    /* It is valid only if FORM is DW_FORM_implicit_const.  */
-    LONGEST implicit_const;
-  };
+  /* It is valid only if FORM is DW_FORM_implicit_const.  */
+  LONGEST implicit_const;
+};
+
+/* This data structure holds the information of an abbrev.  */
+struct abbrev_info
+{
+  /* Number identifying abbrev.  */
+  unsigned int number;
+  /* DWARF tag.  */
+  enum dwarf_tag tag;
+  /* True if the DIE has children.  */
+  unsigned short has_children;
+  /* Number of attributes.  */
+  unsigned short num_attrs;
+  /* An array of attribute descriptions, allocated using the struct
+     hack.  */
+  struct attr_abbrev attrs[1];
+};
 
 struct abbrev_table;
 typedef std::unique_ptr<struct abbrev_table> abbrev_table_up;
@@ -85,10 +91,6 @@ private:
 
   DISABLE_COPY_AND_ASSIGN (abbrev_table);
 
-  /* Allocate space for a struct abbrev_info object in
-     ABBREV_TABLE.  */
-  struct abbrev_info *alloc_abbrev ();
-
   /* Add an abbreviation to the table.  */
   void add_abbrev (struct abbrev_info *abbrev);
 
index d4f13229ced091432692811f3f533fba15d88ea4..f129ea65978d46ece4212d5ff009e3712b7931f8 100644 (file)
@@ -1340,7 +1340,8 @@ static const struct cu_partial_die_info find_partial_die (sect_offset, int,
                                                          struct dwarf2_cu *);
 
 static const gdb_byte *read_attribute (const struct die_reader_specs *,
-                                      struct attribute *, struct attr_abbrev *,
+                                      struct attribute *,
+                                      const struct attr_abbrev *,
                                       const gdb_byte *);
 
 static void read_attribute_reprocess (const struct die_reader_specs *reader,
@@ -20836,7 +20837,7 @@ 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,
+               struct attribute *attr, const struct attr_abbrev *abbrev,
                const gdb_byte *info_ptr)
 {
   attr->name = abbrev->name;