};
/* Each element of dwarf2_per_bfd->type_unit_groups is a pointer to
- an object of this type. */
+ an object of this type. This contains elements of type unit groups
+ that can be shared across objfiles. The non-shareable parts are in
+ type_unit_group_unshareable. */
struct type_unit_group
{
and is deleted afterwards and not used again. */
std::vector<signatured_type *> *tus;
- /* The compunit symtab.
- Type units in a group needn't all be defined in the same source file,
- so we create an essentially anonymous symtab as the compunit symtab. */
- struct compunit_symtab *compunit_symtab;
-
/* The data used to construct the hash key. */
struct stmt_list_hash hash;
-
- /* The symbol tables for this TU (obtained from the files listed in
- DW_AT_stmt_list).
- WARNING: The order of entries here must match the order of entries
- in the line header. After the first TU using this type_unit_group, the
- line header for the subsequent TUs is recreated from this. This is done
- because we need to use the same symtabs for each TU using the same
- DW_AT_stmt_list value. Also note that symtabs may be repeated here,
- there's no guarantee the line header doesn't have duplicate entries. */
- struct symtab **symtabs;
};
/* These sections are what may appear in a (real or virtual) DWO file. */
cu->rust_unions.clear ();
}
+/* See read.h. */
+
+type_unit_group_unshareable *
+dwarf2_per_objfile::get_type_unit_group_unshareable (type_unit_group *tu_group)
+{
+ auto iter = this->m_type_units.find (tu_group);
+ if (iter != this->m_type_units.end ())
+ return iter->second.get ();
+
+ type_unit_group_unshareable_up uniq (new type_unit_group_unshareable);
+ type_unit_group_unshareable *result = uniq.get ();
+ this->m_type_units[tu_group] = std::move (uniq);
+ return result;
+}
+
/* A helper function for computing the list of all symbol tables
included by PER_CU. */
If this is the first TU to use this symtab, complete the construction
of it with end_expandable_symtab. Otherwise, complete the addition of
this TU's symbols to the existing symtab. */
- if (sig_type->type_unit_group->compunit_symtab == NULL)
+ type_unit_group_unshareable *tug_unshare =
+ dwarf2_per_objfile->get_type_unit_group_unshareable (sig_type->type_unit_group);
+ if (tug_unshare->compunit_symtab == NULL)
{
buildsym_compunit *builder = cu->get_builder ();
cust = builder->end_expandable_symtab (0, SECT_OFF_TEXT (objfile));
- sig_type->type_unit_group->compunit_symtab = cust;
+ tug_unshare->compunit_symtab = cust;
if (cust != NULL)
{
else
{
cu->get_builder ()->augment_type_symtab ();
- cust = sig_type->type_unit_group->compunit_symtab;
+ cust = tug_unshare->compunit_symtab;
}
dwarf2_per_objfile->set_symtab (per_cu, cust);
do it again, we could fake it and just recreate the part we need
(file name,index -> symtab mapping). If data shows this optimization
is useful we can do it then. */
- first_time = tu_group->compunit_symtab == NULL;
+ type_unit_group_unshareable *tug_unshare
+ = per_objfile->get_type_unit_group_unshareable (tu_group);
+ first_time = tug_unshare->compunit_symtab == NULL;
/* We have to handle the case of both a missing DW_AT_stmt_list or bad
debug info. */
start_symtab ("", NULL, 0);
else
{
- gdb_assert (tu_group->symtabs == NULL);
+ gdb_assert (tug_unshare->symtabs == NULL);
gdb_assert (m_builder == nullptr);
- struct compunit_symtab *cust = tu_group->compunit_symtab;
+ struct compunit_symtab *cust = tug_unshare->compunit_symtab;
m_builder.reset (new struct buildsym_compunit
(COMPUNIT_OBJFILE (cust), "",
COMPUNIT_DIRNAME (cust),
process_full_type_unit still needs to know if this is the first
time. */
- tu_group->symtabs
+ tug_unshare->symtabs
= XOBNEWVEC (&COMPUNIT_OBJFILE (cust)->objfile_obstack,
struct symtab *, line_header->file_names_size ());
}
fe.symtab = b->get_current_subfile ()->symtab;
- tu_group->symtabs[i] = fe.symtab;
+ tug_unshare->symtabs[i] = fe.symtab;
}
}
else
{
gdb_assert (m_builder == nullptr);
- struct compunit_symtab *cust = tu_group->compunit_symtab;
+ struct compunit_symtab *cust = tug_unshare->compunit_symtab;
m_builder.reset (new struct buildsym_compunit
(COMPUNIT_OBJFILE (cust), "",
COMPUNIT_DIRNAME (cust),
for (i = 0; i < file_names.size (); ++i)
{
file_entry &fe = file_names[i];
- fe.symtab = tu_group->symtabs[i];
+ fe.symtab = tug_unshare->symtabs[i];
}
}
struct mapped_index;
struct mapped_debug_names;
struct signatured_type;
+struct type_unit_group;
/* One item on the queue of compilation units to read in full symbols
for. */
size_t m_num_psymtabs = 0;
};
+/* This is the per-objfile data associated with a type_unit_group. */
+
+struct type_unit_group_unshareable
+{
+ /* The compunit symtab.
+ Type units in a group needn't all be defined in the same source file,
+ so we create an essentially anonymous symtab as the compunit symtab. */
+ struct compunit_symtab *compunit_symtab = nullptr;
+
+ /* The number of symtabs from the line header.
+ The value here must match line_header.num_file_names. */
+ unsigned int num_symtabs = 0;
+
+ /* The symbol tables for this TU (obtained from the files listed in
+ DW_AT_stmt_list).
+ WARNING: The order of entries here must match the order of entries
+ in the line header. After the first TU using this type_unit_group, the
+ line header for the subsequent TUs is recreated from this. This is done
+ because we need to use the same symtabs for each TU using the same
+ DW_AT_stmt_list value. Also note that symtabs may be repeated here,
+ there's no guarantee the line header doesn't have duplicate entries. */
+ struct symtab **symtabs = nullptr;
+};
+
/* Collection of data recorded per objfile.
This hangs off of dwarf2_objfile_data_key.
/* Set the compunit_symtab associated to PER_CU. */
void set_symtab (const dwarf2_per_cu_data *per_cu, compunit_symtab *symtab);
+/* Get the type_unit_group_unshareable corresponding to TU_GROUP. If one
+ does not exist, create it. */
+ type_unit_group_unshareable *get_type_unit_group_unshareable
+ (type_unit_group *tu_group);
+
/* Find an integer type SIZE_IN_BYTES bytes in size and return it.
UNSIGNED_P controls if the integer is unsigned or not. */
struct type *int_type (int size_in_bytes, bool unsigned_p) const;
is indexed by dwarf2_per_cu_data::index. A NULL value means
that the CU/TU has not been expanded yet. */
std::vector<compunit_symtab *> m_symtabs;
+
+ /* Map from a type unit group to the corresponding unshared
+ structure. */
+ typedef std::unique_ptr<type_unit_group_unshareable>
+ type_unit_group_unshareable_up;
+
+ std::unordered_map<type_unit_group *, type_unit_group_unshareable_up>
+ m_type_units;
};
/* Get the dwarf2_per_objfile associated to OBJFILE. */