Move psymtabs to their own obstack

Previously, the psymtab obstack was just a pointer to the objfile
obstack.  This patch changes psymtabs to use their own obstack,
instead.  A gdb::optional is used to avoid unnecessary allocation when
the obstack is not needed.

After this patch, the psymtab code lifetime model is that, in the core
psymtab code, objects allocated on the psymtab obstack may point to
other such objects, or to objects on the per-BFD obstack -- but never
to the objfile obstack.

Note however that this invariant is only obeyed the core psymtab code,
and even there not quite fully: there is still a link from the psymtab
to the full symtab.

Symbol readers are free to work however they like; and in particular,
even after this patch, in practice all symbol readers violate this
invariant via the read_symtab_private field.

gdb/ChangeLog
2019-01-10  Tom Tromey  <tom@tromey.com>

	* objfiles.h (objfile::reset_psymtabs): Update.
	* objfiles.c (objfile::objfile): Update.
	* psymtab.h (psymtab_storage::obstack): Update.
	(psymtab_storage::m_obstack): Use gdb::optional.
	(class psymtab_storage): Update comment.  Remove objfile
	parameter.
	* psymtab.c (psymtab_storage::psymtab_storage): Update.
This commit is contained in:
Tom Tromey 2018-05-10 16:23:57 -06:00
parent b596a3c77d
commit 8d7bcccb82
5 changed files with 35 additions and 10 deletions

View file

@ -1,3 +1,13 @@
2019-01-10 Tom Tromey <tom@tromey.com>
* objfiles.h (objfile::reset_psymtabs): Update.
* objfiles.c (objfile::objfile): Update.
* psymtab.h (psymtab_storage::obstack): Update.
(psymtab_storage::m_obstack): Use gdb::optional.
(class psymtab_storage): Update comment. Remove objfile
parameter.
* psymtab.c (psymtab_storage::psymtab_storage): Update.
2019-01-10 Tom Tromey <tom@tromey.com>
* psymtab.h (psymtab_storage::allocate_psymtab): New method.

View file

@ -369,7 +369,7 @@ build_objfile_section_table (struct objfile *objfile)
objfile::objfile (bfd *abfd, const char *name, objfile_flags flags_)
: flags (flags_),
pspace (current_program_space),
partial_symtabs (new psymtab_storage (this)),
partial_symtabs (new psymtab_storage ()),
obfd (abfd)
{
const char *expanded_name;

View file

@ -298,7 +298,7 @@ struct objfile
void reset_psymtabs ()
{
psymbol_map.clear ();
partial_symtabs.reset (new psymtab_storage (this));
partial_symtabs.reset (new psymtab_storage ());
}

View file

@ -67,9 +67,8 @@ static struct compunit_symtab *psymtab_to_symtab (struct objfile *objfile,
psymtab_storage::psymtab_storage (struct objfile *objfile)
: psymbol_cache (psymbol_bcache_init ()),
m_obstack (&objfile->objfile_obstack)
psymtab_storage::psymtab_storage ()
: psymbol_cache (psymbol_bcache_init ())
{
}

View file

@ -31,13 +31,26 @@ struct partial_symbol;
struct psymbol_bcache;
/* An instance of this class manages the partial symbol tables and
partial symbols for a given objfile. */
partial symbols for a given objfile.
The core psymtab functions -- those in psymtab.c -- arrange for
nearly all psymtab- and psymbol-related allocations to happen
either in the psymtab_storage object (either on its obstack or in
other memory managed by this class), or on the per-BFD object. The
only link from the psymtab storage object back to the objfile (or
objfile_obstack) that is made by the core psymtab code is the
compunit_symtab member in the psymtab.
However, it is up to each symbol reader to maintain this invariant
in other ways, if it wants to reuse psymtabs across multiple
objfiles. The main issue here is ensuring that read_symtab_private
does not point into objfile_obstack. */
class psymtab_storage
{
public:
explicit psymtab_storage (struct objfile *objfile);
psymtab_storage ();
~psymtab_storage ();
@ -60,7 +73,9 @@ public:
struct obstack *obstack ()
{
return m_obstack;
if (!m_obstack.has_value ())
m_obstack.emplace ();
return &*m_obstack;
}
/* Allocate storage for the "dependencies" field of a psymtab.
@ -108,9 +123,10 @@ private:
struct partial_symtab *free_psymtabs = nullptr;
/* The obstack where allocations are made. */
/* The obstack where allocations are made. This is lazily allocated
so that we don't waste memory when there are no psymtabs. */
struct obstack *m_obstack;
gdb::optional<auto_obstack> m_obstack;
};