From 4444f40757a242015973237627283a910f5d9654 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sat, 6 Mar 2021 09:16:59 -0700 Subject: [PATCH] Micro-optimize abbrev reading and storage 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 * 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. : Now an array. (struct abbrev_table) : Remove. --- gdb/ChangeLog | 10 +++++++ gdb/dwarf2/abbrev.c | 71 +++++++++++++++++---------------------------- gdb/dwarf2/abbrev.h | 42 ++++++++++++++------------- gdb/dwarf2/read.c | 5 ++-- 4 files changed, 61 insertions(+), 67 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ef9e2d8a13d..91b7a68894f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2021-03-06 Tom Tromey + + * 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. + : Now an array. + (struct abbrev_table) : Remove. + 2021-03-06 Weimin Pan * ctfread.c (ctf_psymtab_add_enums): New function. diff --git a/gdb/dwarf2/abbrev.c b/gdb/dwarf2/abbrev.c index 6219c13a94b..9ece708a1ac 100644 --- a/gdb/dwarf2/abbrev.c +++ b/gdb/dwarf2/abbrev.c @@ -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 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. diff --git a/gdb/dwarf2/abbrev.h b/gdb/dwarf2/abbrev.h index 8018f49cf08..e1d8b80619b 100644 --- a/gdb/dwarf2/abbrev.h +++ b/gdb/dwarf2/abbrev.h @@ -29,24 +29,30 @@ #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 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); diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index d4f13229ced..f129ea65978 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -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; -- 2.30.2