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  <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.
This commit is contained in:
Tom Tromey
2021-03-06 09:16:59 -07:00
parent 8c0546e928
commit 4444f40757
4 changed files with 61 additions and 67 deletions

View 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.

View 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.

View File

@@ -29,24 +29,30 @@
#include "hashtab.h"
struct attr_abbrev
{
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;
};
/* 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;
/* It is valid only if FORM is DW_FORM_implicit_const. */
LONGEST implicit_const;
};
{
/* 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);

View 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;