Rewrite registry.h

This rewrites registry.h, removing all the macros and replacing it
with relatively ordinary template classes.  The result is less code
than the previous setup.  It replaces large macros with a relatively
straightforward C++ class, and now manages its own cleanup.

The existing type-safe "key" class is replaced with the equivalent
template class.  This approach ended up requiring relatively few
changes to the users of the registry code in gdb -- code using the key
system just required a small change to the key's declaration.

All existing users of the old C-like API are now converted to use the
type-safe API.  This mostly involved changing explicit deletion
functions to be an operator() in a deleter class.

The old "save/free" two-phase process is removed, and replaced with a
single "free" phase.  No existing code used both phases.

The old "free" callbacks took a parameter for the enclosing container
object.  However, this wasn't truly needed and is removed here as
well.
This commit is contained in:
Tom Tromey 2020-10-18 11:38:10 -06:00
parent 8f83e7b926
commit 08b8a139c9
64 changed files with 664 additions and 1052 deletions

View file

@ -37,9 +37,31 @@ struct symtab_object {
symtab_object *next;
};
/* This function is called when an objfile is about to be freed.
Invalidate the symbol table as further actions on the symbol table
would result in bad data. All access to obj->symtab should be
gated by STPY_REQUIRE_VALID which will raise an exception on
invalid symbol tables. */
struct stpy_deleter
{
void operator() (symtab_object *obj)
{
while (obj)
{
symtab_object *next = obj->next;
obj->symtab = NULL;
obj->next = NULL;
obj->prev = NULL;
obj = next;
}
}
};
extern PyTypeObject symtab_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("symtab_object");
static const struct objfile_data *stpy_objfile_data_key;
static const registry<objfile>::key<symtab_object, stpy_deleter>
stpy_objfile_data_key;
/* Require a valid symbol table. All access to symtab_object->symtab
should be gated by this call. */
@ -68,9 +90,39 @@ struct sal_object {
sal_object *next;
};
/* This is called when an objfile is about to be freed. Invalidate
the sal object as further actions on the sal would result in bad
data. All access to obj->sal should be gated by
SALPY_REQUIRE_VALID which will raise an exception on invalid symbol
table and line objects. */
struct salpy_deleter
{
void operator() (sal_object *obj)
{
gdbpy_enter enter_py;
while (obj)
{
sal_object *next = obj->next;
gdbpy_ref<> tmp (obj->symtab);
obj->symtab = Py_None;
Py_INCREF (Py_None);
obj->next = NULL;
obj->prev = NULL;
xfree (obj->sal);
obj->sal = NULL;
obj = next;
}
}
};
extern PyTypeObject sal_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("sal_object");
static const struct objfile_data *salpy_objfile_data_key;
static const registry<objfile>::key<sal_object, salpy_deleter>
salpy_objfile_data_key;
/* Require a valid symbol table and line object. All access to
sal_object->sal should be gated by this call. */
@ -246,10 +298,8 @@ stpy_dealloc (PyObject *obj)
if (symtab->prev)
symtab->prev->next = symtab->next;
else if (symtab->symtab)
{
set_objfile_data (symtab->symtab->compunit ()->objfile (),
stpy_objfile_data_key, symtab->next);
}
stpy_objfile_data_key.set (symtab->symtab->compunit ()->objfile (),
symtab->next);
if (symtab->next)
symtab->next->prev = symtab->prev;
symtab->symtab = NULL;
@ -329,9 +379,9 @@ salpy_dealloc (PyObject *self)
if (self_sal->prev)
self_sal->prev->next = self_sal->next;
else if (self_sal->symtab != Py_None)
set_objfile_data
salpy_objfile_data_key.set
(symtab_object_to_symtab (self_sal->symtab)->compunit ()->objfile (),
salpy_objfile_data_key, self_sal->next);
self_sal->next);
if (self_sal->next)
self_sal->next->prev = self_sal->prev;
@ -378,13 +428,11 @@ set_sal (sal_object *sal_obj, struct symtab_and_line sal)
symtab *symtab = symtab_object_to_symtab (sal_obj->symtab);
sal_obj->next
= ((sal_object *) objfile_data (symtab->compunit ()->objfile (),
salpy_objfile_data_key));
= salpy_objfile_data_key.get (symtab->compunit ()->objfile ());
if (sal_obj->next)
sal_obj->next->prev = sal_obj;
set_objfile_data (symtab->compunit ()->objfile (),
salpy_objfile_data_key, sal_obj);
salpy_objfile_data_key.set (symtab->compunit ()->objfile (), sal_obj);
}
else
sal_obj->next = NULL;
@ -404,14 +452,10 @@ set_symtab (symtab_object *obj, struct symtab *symtab)
obj->prev = NULL;
if (symtab)
{
obj->next
= ((symtab_object *)
objfile_data (symtab->compunit ()->objfile (),
stpy_objfile_data_key));
obj->next = stpy_objfile_data_key.get (symtab->compunit ()->objfile ());
if (obj->next)
obj->next->prev = obj;
set_objfile_data (symtab->compunit ()->objfile (),
stpy_objfile_data_key, obj);
stpy_objfile_data_key.set (symtab->compunit ()->objfile (), obj);
}
else
obj->next = NULL;
@ -465,68 +509,6 @@ symtab_object_to_symtab (PyObject *obj)
return ((symtab_object *) obj)->symtab;
}
/* This function is called when an objfile is about to be freed.
Invalidate the symbol table as further actions on the symbol table
would result in bad data. All access to obj->symtab should be
gated by STPY_REQUIRE_VALID which will raise an exception on
invalid symbol tables. */
static void
del_objfile_symtab (struct objfile *objfile, void *datum)
{
symtab_object *obj = (symtab_object *) datum;
while (obj)
{
symtab_object *next = obj->next;
obj->symtab = NULL;
obj->next = NULL;
obj->prev = NULL;
obj = next;
}
}
/* This function is called when an objfile is about to be freed.
Invalidate the sal object as further actions on the sal
would result in bad data. All access to obj->sal should be
gated by SALPY_REQUIRE_VALID which will raise an exception on
invalid symbol table and line objects. */
static void
del_objfile_sal (struct objfile *objfile, void *datum)
{
sal_object *obj = (sal_object *) datum;
while (obj)
{
sal_object *next = obj->next;
gdbpy_ref<> tmp (obj->symtab);
obj->symtab = Py_None;
Py_INCREF (Py_None);
obj->next = NULL;
obj->prev = NULL;
xfree (obj->sal);
obj->sal = NULL;
obj = next;
}
}
void _initialize_py_symtab ();
void
_initialize_py_symtab ()
{
/* Register an objfile "free" callback so we can properly
invalidate symbol tables, and symbol table and line data
structures when an object file that is about to be
deleted. */
stpy_objfile_data_key
= register_objfile_data_with_cleanup (NULL, del_objfile_symtab);
salpy_objfile_data_key
= register_objfile_data_with_cleanup (NULL, del_objfile_sal);
}
int
gdbpy_initialize_symtabs (void)
{