Re-write partial_die_info allocation in load_partial_dies
authorYao Qi <yao.qi@linaro.org>
Mon, 26 Feb 2018 15:38:00 +0000 (15:38 +0000)
committerYao Qi <yao.qi@linaro.org>
Mon, 26 Feb 2018 15:38:00 +0000 (15:38 +0000)
load_partial_dies has a "while (1)" loop to visit each die, and create
partial_die_info if needed in each iteration, like this,

  part_die = XOBNEW (&cu->comp_unit_obstack, struct partial_die_info);

  while (1)
   {
      if (foo1) continue;

      if (foo2) continue;

      read_partial_die (, , part_die, ,);

      ....
      part_die = XOBNEW (&cu->comp_unit_obstack, struct partial_die_info);
   };

the code was written in a way that spaces are allocated on necessary on
cu->comp_unit_obstack.  I want to class-fy partial_die_info, but
partial_die_info ctor can't follow XOBNEW immediately, so this patch
rewrite this loop to:

  while (1)
   {
      if (foo1) continue;

      if (foo2) continue;

      struct partial_die_info pdi;
      read_partial_die (, , &pdi, ,);

      part_die = XOBNEW (&cu->comp_unit_obstack, struct partial_die_info);
      memcpy (part_die, &pdi, sizeof (pdi));
   };

we create a local variable pdi, if we need it, call XOBNEW, and copy.
This also reduce one XOBNEW call.  I measured the number of XOBNEW call in
load_partial_dies when gdb reads dwarf2read.o, without this patch, it is
18827, and with this patch, it is 18826.

gdb:

2018-026-26  Yao Qi  <yao.qi@linaro.org>

* dwarf2read.c (load_partial_dies): Move the location of XOBNEW.

gdb/ChangeLog
gdb/dwarf2read.c

index 14e7914..a5238b7 100644 (file)
@@ -1,3 +1,7 @@
+2018-02-26  Yao Qi  <yao.qi@linaro.org>
+
+       * dwarf2read.c (load_partial_dies): Move the location of XOBNEW.
+
 2018-02-26  Alan Hayward  <alan.hayward@arm.com>
 
        * arch/amd64.h: Use common/tdesc.h.
index c8c805a..ab9bfed 100644 (file)
@@ -18219,7 +18219,6 @@ load_partial_dies (const struct die_reader_specs *reader,
 {
   struct dwarf2_cu *cu = reader->cu;
   struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
-  struct partial_die_info *part_die;
   struct partial_die_info *parent_die, *last_die, *first_die = NULL;
   unsigned int bytes_read;
   unsigned int load_all = 0;
@@ -18241,8 +18240,6 @@ load_partial_dies (const struct die_reader_specs *reader,
                            hashtab_obstack_allocate,
                            dummy_obstack_deallocate);
 
-  part_die = XOBNEW (&cu->comp_unit_obstack, struct partial_die_info);
-
   while (1)
     {
       abbrev_info *abbrev = peek_die_abbrev (*reader, info_ptr, &bytes_read);
@@ -18251,15 +18248,8 @@ load_partial_dies (const struct die_reader_specs *reader,
       if (abbrev == NULL)
        {
          if (--nesting_level == 0)
-           {
-             /* PART_DIE was probably the last thing allocated on the
-                comp_unit_obstack, so we could call obstack_free
-                here.  We don't do that because the waste is small,
-                and will be cleaned up when we're done with this
-                compilation unit.  This way, we're also more robust
-                against other users of the comp_unit_obstack.  */
-             return first_die;
-           }
+           return first_die;
+
          info_ptr += bytes_read;
          last_die = parent_die;
          parent_die = parent_die->die_parent;
@@ -18317,7 +18307,10 @@ load_partial_dies (const struct die_reader_specs *reader,
          continue;
        }
 
-      info_ptr = read_partial_die (reader, part_die, abbrev, bytes_read,
+      struct partial_die_info pdi;
+
+      memset (&pdi, 0, sizeof (pdi));
+      info_ptr = read_partial_die (reader, &pdi, abbrev, bytes_read,
                                   info_ptr);
 
       /* This two-pass algorithm for processing partial symbols has a
@@ -18337,18 +18330,18 @@ load_partial_dies (const struct die_reader_specs *reader,
         of them, for a language without namespaces), can be processed
         directly.  */
       if (parent_die == NULL
-         && part_die->has_specification == 0
-         && part_die->is_declaration == 0
-         && ((part_die->tag == DW_TAG_typedef && !part_die->has_children)
-             || part_die->tag == DW_TAG_base_type
-             || part_die->tag == DW_TAG_subrange_type))
-       {
-         if (building_psymtab && part_die->name != NULL)
-           add_psymbol_to_list (part_die->name, strlen (part_die->name), 0,
+         && pdi.has_specification == 0
+         && pdi.is_declaration == 0
+         && ((pdi.tag == DW_TAG_typedef && !pdi.has_children)
+             || pdi.tag == DW_TAG_base_type
+             || pdi.tag == DW_TAG_subrange_type))
+       {
+         if (building_psymtab && pdi.name != NULL)
+           add_psymbol_to_list (pdi.name, strlen (pdi.name), 0,
                                 VAR_DOMAIN, LOC_TYPEDEF,
                                 &objfile->static_psymbols,
                                 0, cu->language, objfile);
-         info_ptr = locate_pdi_sibling (reader, part_die, info_ptr);
+         info_ptr = locate_pdi_sibling (reader, &pdi, info_ptr);
          continue;
        }
 
@@ -18360,37 +18353,41 @@ load_partial_dies (const struct die_reader_specs *reader,
         it could not find the child DIEs referenced later, this is checked
         above.  In correct DWARF DW_TAG_typedef should have no children.  */
 
-      if (part_die->tag == DW_TAG_typedef && part_die->has_children)
+      if (pdi.tag == DW_TAG_typedef && pdi.has_children)
        complaint (&symfile_complaints,
                   _("DW_TAG_typedef has childen - GCC PR debug/47510 bug "
                     "- DIE at %s [in module %s]"),
-                  sect_offset_str (part_die->sect_off), objfile_name (objfile));
+                  sect_offset_str (pdi.sect_off), objfile_name (objfile));
 
       /* If we're at the second level, and we're an enumerator, and
         our parent has no specification (meaning possibly lives in a
         namespace elsewhere), then we can add the partial symbol now
         instead of queueing it.  */
-      if (part_die->tag == DW_TAG_enumerator
+      if (pdi.tag == DW_TAG_enumerator
          && parent_die != NULL
          && parent_die->die_parent == NULL
          && parent_die->tag == DW_TAG_enumeration_type
          && parent_die->has_specification == 0)
        {
-         if (part_die->name == NULL)
+         if (pdi.name == NULL)
            complaint (&symfile_complaints,
                       _("malformed enumerator DIE ignored"));
          else if (building_psymtab)
-           add_psymbol_to_list (part_die->name, strlen (part_die->name), 0,
+           add_psymbol_to_list (pdi.name, strlen (pdi.name), 0,
                                 VAR_DOMAIN, LOC_CONST,
                                 cu->language == language_cplus
                                 ? &objfile->global_psymbols
                                 : &objfile->static_psymbols,
                                 0, cu->language, objfile);
 
-         info_ptr = locate_pdi_sibling (reader, part_die, info_ptr);
+         info_ptr = locate_pdi_sibling (reader, &pdi, info_ptr);
          continue;
        }
 
+      struct partial_die_info *part_die
+         = XOBNEW (&cu->comp_unit_obstack, struct partial_die_info);
+
+      memcpy (part_die, &pdi, sizeof (pdi));
       /* We'll save this DIE so link it in.  */
       part_die->die_parent = parent_die;
       part_die->die_sibling = NULL;
@@ -18442,8 +18439,6 @@ load_partial_dies (const struct die_reader_specs *reader,
          *slot = part_die;
        }
 
-      part_die = XOBNEW (&cu->comp_unit_obstack, struct partial_die_info);
-
       /* For some DIEs we want to follow their children (if any).  For C
         we have no reason to follow the children of structures; for other
         languages we have to, so that we can get at method physnames