Reduce manual reference counting in py-inferior.c

This patch changes py-inferior.c to use gdbpy_ref<> when possible,
reducing the amount of manual reference counting.

Tested on x86-64 Fedora 29.

gdb/ChangeLog
2019-07-10  Tom Tromey  <tromey@adacore.com>

	* python/python-internal.h (create_thread_object): Return
	gdbpy_ref.
	* python/py-infthread.c (create_thread_object): Return gdbpy_ref.
	* python/py-inferior.c (struct threadlist_entry): Add
	constructor.
	<thread_obj>: Now a gdbpy_ref.
	(thread_to_thread_object): Update.
	(add_thread_object): Use new.
	(delete_thread_object): Use delete.
	(infpy_threads): Update.
	(py_free_inferior): Update.  Construct "inf_obj" after acquiring
	GIL.
This commit is contained in:
Tom Tromey 2019-06-28 08:32:28 -06:00
parent 32372d80ca
commit 05b08ac160
4 changed files with 39 additions and 22 deletions

View File

@ -1,3 +1,18 @@
2019-07-10 Tom Tromey <tromey@adacore.com>
* python/python-internal.h (create_thread_object): Return
gdbpy_ref.
* python/py-infthread.c (create_thread_object): Return gdbpy_ref.
* python/py-inferior.c (struct threadlist_entry): Add
constructor.
<thread_obj>: Now a gdbpy_ref.
(thread_to_thread_object): Update.
(add_thread_object): Use new.
(delete_thread_object): Use delete.
(infpy_threads): Update.
(py_free_inferior): Update. Construct "inf_obj" after acquiring
GIL.
2019-07-10 Tom Tromey <tromey@adacore.com> 2019-07-10 Tom Tromey <tromey@adacore.com>
* valops.c (value_cast): Specialize error message for Ada. * valops.c (value_cast): Specialize error message for Ada.

View File

@ -30,8 +30,14 @@
#include "py-event.h" #include "py-event.h"
#include "py-stopevent.h" #include "py-stopevent.h"
struct threadlist_entry { struct threadlist_entry
thread_object *thread_obj; {
threadlist_entry (gdbpy_ref<thread_object> &&ref)
: thread_obj (std::move (ref))
{
}
gdbpy_ref<thread_object> thread_obj;
struct threadlist_entry *next; struct threadlist_entry *next;
}; };
@ -301,7 +307,7 @@ thread_to_thread_object (thread_info *thr)
thread != NULL; thread != NULL;
thread = thread->next) thread = thread->next)
if (thread->thread_obj->thread == thr) if (thread->thread_obj->thread == thr)
return gdbpy_ref<>::new_reference ((PyObject *) thread->thread_obj); return gdbpy_ref<>::new_reference ((PyObject *) thread->thread_obj.get ());
PyErr_SetString (PyExc_SystemError, PyErr_SetString (PyExc_SystemError,
_("could not find gdb thread object")); _("could not find gdb thread object"));
@ -311,7 +317,6 @@ thread_to_thread_object (thread_info *thr)
static void static void
add_thread_object (struct thread_info *tp) add_thread_object (struct thread_info *tp)
{ {
thread_object *thread_obj;
inferior_object *inf_obj; inferior_object *inf_obj;
struct threadlist_entry *entry; struct threadlist_entry *entry;
@ -320,8 +325,8 @@ add_thread_object (struct thread_info *tp)
gdbpy_enter enter_py (python_gdbarch, python_language); gdbpy_enter enter_py (python_gdbarch, python_language);
thread_obj = create_thread_object (tp); gdbpy_ref<thread_object> thread_obj = create_thread_object (tp);
if (!thread_obj) if (thread_obj == NULL)
{ {
gdbpy_print_stack (); gdbpy_print_stack ();
return; return;
@ -329,8 +334,7 @@ add_thread_object (struct thread_info *tp)
inf_obj = (inferior_object *) thread_obj->inf_obj; inf_obj = (inferior_object *) thread_obj->inf_obj;
entry = XNEW (struct threadlist_entry); entry = new threadlist_entry (std::move (thread_obj));
entry->thread_obj = thread_obj;
entry->next = inf_obj->threads; entry->next = inf_obj->threads;
inf_obj->threads = entry; inf_obj->threads = entry;
@ -340,7 +344,7 @@ add_thread_object (struct thread_info *tp)
return; return;
gdbpy_ref<> event = create_thread_event_object (&new_thread_event_object_type, gdbpy_ref<> event = create_thread_event_object (&new_thread_event_object_type,
(PyObject *) thread_obj); (PyObject *) thread_obj.get ());
if (event == NULL if (event == NULL
|| evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0) || evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0)
gdbpy_print_stack (); gdbpy_print_stack ();
@ -375,8 +379,7 @@ delete_thread_object (struct thread_info *tp, int ignore)
*entry = (*entry)->next; *entry = (*entry)->next;
inf_obj->nthreads--; inf_obj->nthreads--;
Py_DECREF (tmp->thread_obj); delete tmp;
xfree (tmp);
} }
static PyObject * static PyObject *
@ -405,8 +408,9 @@ infpy_threads (PyObject *self, PyObject *args)
for (i = 0, entry = inf_obj->threads; i < inf_obj->nthreads; for (i = 0, entry = inf_obj->threads; i < inf_obj->nthreads;
i++, entry = entry->next) i++, entry = entry->next)
{ {
Py_INCREF (entry->thread_obj); PyObject *thr = (PyObject *) entry->thread_obj.get ();
PyTuple_SET_ITEM (tuple, i, (PyObject *) entry->thread_obj); Py_INCREF (thr);
PyTuple_SET_ITEM (tuple, i, thr);
} }
return tuple; return tuple;
@ -859,24 +863,22 @@ infpy_dealloc (PyObject *obj)
static void static void
py_free_inferior (struct inferior *inf, void *datum) py_free_inferior (struct inferior *inf, void *datum)
{ {
gdbpy_ref<inferior_object> inf_obj ((inferior_object *) datum);
struct threadlist_entry *th_entry, *th_tmp; struct threadlist_entry *th_entry, *th_tmp;
if (!gdb_python_initialized) if (!gdb_python_initialized)
return; return;
gdbpy_enter enter_py (python_gdbarch, python_language); gdbpy_enter enter_py (python_gdbarch, python_language);
gdbpy_ref<inferior_object> inf_obj ((inferior_object *) datum);
inf_obj->inferior = NULL; inf_obj->inferior = NULL;
/* Deallocate threads list. */ /* Deallocate threads list. */
for (th_entry = inf_obj->threads; th_entry != NULL;) for (th_entry = inf_obj->threads; th_entry != NULL;)
{ {
Py_DECREF (th_entry->thread_obj);
th_tmp = th_entry; th_tmp = th_entry;
th_entry = th_entry->next; th_entry = th_entry->next;
xfree (th_tmp); delete th_tmp;
} }
inf_obj->nthreads = 0; inf_obj->nthreads = 0;

View File

@ -36,17 +36,17 @@ extern PyTypeObject thread_object_type
} \ } \
} while (0) } while (0)
thread_object * gdbpy_ref<thread_object>
create_thread_object (struct thread_info *tp) create_thread_object (struct thread_info *tp)
{ {
thread_object *thread_obj; gdbpy_ref<thread_object> thread_obj;
gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (tp->inf); gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (tp->inf);
if (inf_obj == NULL) if (inf_obj == NULL)
return NULL; return NULL;
thread_obj = PyObject_New (thread_object, &thread_object_type); thread_obj.reset (PyObject_New (thread_object, &thread_object_type));
if (!thread_obj) if (thread_obj == NULL)
return NULL; return NULL;
thread_obj->thread = tp; thread_obj->thread = tp;

View File

@ -468,7 +468,7 @@ PyObject *gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw);
PyObject *gdbarch_to_arch_object (struct gdbarch *gdbarch); PyObject *gdbarch_to_arch_object (struct gdbarch *gdbarch);
thread_object *create_thread_object (struct thread_info *tp); gdbpy_ref<thread_object> create_thread_object (struct thread_info *tp);
gdbpy_ref<> thread_to_thread_object (thread_info *thr);; gdbpy_ref<> thread_to_thread_object (thread_info *thr);;
gdbpy_ref<inferior_object> inferior_to_inferior_object (inferior *inf); gdbpy_ref<inferior_object> inferior_to_inferior_object (inferior *inf);