From cd9983dd5f16803aa60e9fe1692b7e6716ac3927 Mon Sep 17 00:00:00 2001 From: Yao Qi Date: Mon, 26 Feb 2018 15:38:00 +0000 Subject: [PATCH] Re-write partial_die_info allocation in load_partial_dies 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 * dwarf2read.c (load_partial_dies): Move the location of XOBNEW. --- gdb/ChangeLog | 4 ++++ gdb/dwarf2read.c | 55 ++++++++++++++++++++++-------------------------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 14e79140563..a5238b7de82 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,7 @@ +2018-02-26 Yao Qi + + * dwarf2read.c (load_partial_dies): Move the location of XOBNEW. + 2018-02-26 Alan Hayward * arch/amd64.h: Use common/tdesc.h. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index c8c805adaec..ab9bfed395a 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -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 -- 2.30.2