From 4e7a5ef5a84e2f120a52def047ef671f8dbd7954 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Thu, 13 Aug 2009 18:39:20 +0000 Subject: [PATCH] * varobj.c (update_dynamic_varobj_children): Don't use value_copy. * value.h: (preserve_one_value): Declare. (value_prepend_to_list, value_remove_from_list): Remove. * value.c (preserve_one_value): No longer static. (preserve_values): Call preserve_python_values. (value_prepend_to_list): Remove. (value_remove_from_list): Remove. * python/python.h (values_in_python): Don't declare. (preserve_python_values): Declare. * python/python-value.c (values_in_python): Change type. Move lower. Now static. (struct value_object): Add struct tag. : New fields. (valpy_dealloc): Update. (note_value): New function. (valpy_new): Use value_incref, note_value. (preserve_python_values): New function. (valpy_positive): Don't use value_copy. (value_to_value_object): Use value_incref, note_value. (convert_value_from_python): Update comment. --- gdb/ChangeLog | 24 ++++++++++++ gdb/python/python-value.c | 79 +++++++++++++++++++++++++++++---------- gdb/python/python.h | 4 +- gdb/value.c | 30 +-------------- gdb/value.h | 7 +--- gdb/varobj.c | 11 +----- 6 files changed, 90 insertions(+), 65 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0dd69cbeeb8..bdcafe6a518 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,27 @@ +2009-08-13 Tom Tromey + + * varobj.c (update_dynamic_varobj_children): Don't use + value_copy. + * value.h: (preserve_one_value): Declare. + (value_prepend_to_list, value_remove_from_list): Remove. + * value.c (preserve_one_value): No longer static. + (preserve_values): Call preserve_python_values. + (value_prepend_to_list): Remove. + (value_remove_from_list): Remove. + * python/python.h (values_in_python): Don't declare. + (preserve_python_values): Declare. + * python/python-value.c (values_in_python): Change type. Move + lower. Now static. + (struct value_object): Add struct tag. + : New fields. + (valpy_dealloc): Update. + (note_value): New function. + (valpy_new): Use value_incref, note_value. + (preserve_python_values): New function. + (valpy_positive): Don't use value_copy. + (value_to_value_object): Use value_incref, note_value. + (convert_value_from_python): Update comment. + 2009-08-13 Pedro Alves * remote.c (remote_pid_to_str): If printing a process id and we diff --git a/gdb/python/python-value.c b/gdb/python/python-value.c index dd3c919786c..c73c916f058 100644 --- a/gdb/python/python-value.c +++ b/gdb/python/python-value.c @@ -26,15 +26,6 @@ #include "dfp.h" #include "valprint.h" -/* List of all values which are currently exposed to Python. It is - maintained so that when an objfile is discarded, preserve_values - can copy the values' types if needed. This is declared - unconditionally to reduce the number of uses of HAVE_PYTHON in the - generic code. */ -/* This variable is unnecessarily initialized to NULL in order to - work around a linker bug on MacOS. */ -struct value *values_in_python = NULL; - #ifdef HAVE_PYTHON #include "python-internal.h" @@ -58,20 +49,38 @@ struct value *values_in_python = NULL; #define builtin_type_pychar \ language_string_char_type (python_language, python_gdbarch) -typedef struct { +typedef struct value_object { PyObject_HEAD + struct value_object *next; + struct value_object *prev; struct value *value; PyObject *address; PyObject *type; } value_object; +/* List of all values which are currently exposed to Python. It is + maintained so that when an objfile is discarded, preserve_values + can copy the values' types if needed. */ +/* This variable is unnecessarily initialized to NULL in order to + work around a linker bug on MacOS. */ +static value_object *values_in_python = NULL; + /* Called by the Python interpreter when deallocating a value object. */ static void valpy_dealloc (PyObject *obj) { value_object *self = (value_object *) obj; - value_remove_from_list (&values_in_python, self->value); + /* Remove SELF from the global list. */ + if (self->prev) + self->prev->next = self->next; + else + { + gdb_assert (values_in_python == self); + values_in_python = self->next; + } + if (self->next) + self->next->prev = self->prev; value_free (self->value); @@ -89,6 +98,17 @@ valpy_dealloc (PyObject *obj) self->ob_type->tp_free (self); } +/* Helper to push a Value object on the global list. */ +static void +note_value (value_object *value_obj) +{ + value_obj->next = values_in_python; + if (value_obj->next) + value_obj->next->prev = value_obj; + value_obj->prev = NULL; + values_in_python = value_obj; +} + /* Called when a new gdb.Value object needs to be allocated. */ static PyObject * valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords) @@ -119,14 +139,25 @@ valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords) } value_obj->value = value; + value_incref (value); value_obj->address = NULL; value_obj->type = NULL; - release_value (value); - value_prepend_to_list (&values_in_python, value); + note_value (value_obj); return (PyObject *) value_obj; } +/* Iterate over all the Value objects, calling preserve_one_value on + each. */ +void +preserve_python_values (struct objfile *objfile, htab_t copied_types) +{ + value_object *iter; + + for (iter = values_in_python; iter; iter = iter->next) + preserve_one_value (iter->value, objfile, copied_types); +} + /* Given a value of a pointer type, apply the C unary * operator to it. */ static PyObject * valpy_dereference (PyObject *self, PyObject *args) @@ -543,9 +574,7 @@ valpy_negative (PyObject *self) static PyObject * valpy_positive (PyObject *self) { - struct value *copy = value_copy (((value_object *) self)->value); - - return value_to_value_object (copy); + return value_to_value_object (((value_object *) self)->value); } static PyObject * @@ -800,16 +829,17 @@ value_to_value_object (struct value *val) if (val_obj != NULL) { val_obj->value = val; + value_incref (val); val_obj->address = NULL; val_obj->type = NULL; - release_value (val); - value_prepend_to_list (&values_in_python, val); + note_value (val_obj); } return (PyObject *) val_obj; } -/* Returns value structure corresponding to the given value object. */ +/* Returns a borrowed reference to the struct value corresponding to + the given value object. */ struct value * value_object_to_value (PyObject *self) { @@ -821,7 +851,8 @@ value_object_to_value (PyObject *self) } /* Try to convert a Python value to a gdb value. If the value cannot - be converted, set a Python exception and return NULL. */ + be converted, set a Python exception and return NULL. Returns a + reference to a new value on the all_values chain. */ struct value * convert_value_from_python (PyObject *obj) @@ -1019,4 +1050,12 @@ PyTypeObject value_object_type = { valpy_new /* tp_new */ }; +#else + +void +preserve_python_values (struct objfile *objfile, htab_t copied_types) +{ + /* Nothing. */ +} + #endif /* HAVE_PYTHON */ diff --git a/gdb/python/python.h b/gdb/python/python.h index 33b0437bd70..e97018090c5 100644 --- a/gdb/python/python.h +++ b/gdb/python/python.h @@ -22,8 +22,6 @@ #include "value.h" -extern struct value *values_in_python; - void eval_python_from_control_command (struct command_line *); int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, @@ -32,4 +30,6 @@ int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, const struct value_print_options *options, const struct language_defn *language); +void preserve_python_values (struct objfile *objfile, htab_t copied_types); + #endif /* GDB_PYTHON_H */ diff --git a/gdb/value.c b/gdb/value.c index 65a5aa93745..97f236c5e9d 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -312,31 +312,6 @@ allocate_repeat_value (struct type *type, int count) return allocate_value (array_type); } -/* Needed if another module needs to maintain its on list of values. */ -void -value_prepend_to_list (struct value **head, struct value *val) -{ - val->next = *head; - *head = val; -} - -/* Needed if another module needs to maintain its on list of values. */ -void -value_remove_from_list (struct value **head, struct value *val) -{ - struct value *prev; - - if (*head == val) - *head = (*head)->next; - else - for (prev = *head; prev->next; prev = prev->next) - if (prev->next == val) - { - prev->next = val->next; - break; - } -} - struct value * allocate_computed_value (struct type *type, struct lval_funcs *funcs, @@ -1430,7 +1405,7 @@ add_internal_function (const char *name, const char *doc, /* Update VALUE before discarding OBJFILE. COPIED_TYPES is used to prevent cycles / duplicates. */ -static void +void preserve_one_value (struct value *value, struct objfile *objfile, htab_t copied_types) { @@ -1490,8 +1465,7 @@ preserve_values (struct objfile *objfile) for (var = internalvars; var; var = var->next) preserve_one_internalvar (var, objfile, copied_types); - for (val = values_in_python; val; val = val->next) - preserve_one_value (val, objfile, copied_types); + preserve_python_values (objfile, copied_types); htab_delete (copied_types); } diff --git a/gdb/value.h b/gdb/value.h index 29ad783d429..6f6b756085f 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -41,11 +41,6 @@ struct value_print_options; struct value; -/* Needed if another module needs to maintain its own list of values. */ - -void value_prepend_to_list (struct value **head, struct value *val); -void value_remove_from_list (struct value **head, struct value *val); - /* Values are stored in a chain, so that they can be deleted easily over calls to the inferior. Values assigned to internal variables, put into the value history or exposed to Python are taken off this @@ -664,6 +659,8 @@ extern void preserve_values (struct objfile *); extern struct value *value_copy (struct value *); +extern void preserve_one_value (struct value *, struct objfile *, htab_t); + /* From valops.c */ extern struct value *varying_to_slice (struct value *); diff --git a/gdb/varobj.c b/gdb/varobj.c index 4a94988b572..48d4cfb7fed 100644 --- a/gdb/varobj.c +++ b/gdb/varobj.c @@ -899,16 +899,7 @@ update_dynamic_varobj_children (struct varobj *var, if (!PyArg_ParseTuple (item, "sO", &name, &py_v)) error (_("Invalid item from the child list")); - if (PyObject_TypeCheck (py_v, &value_object_type)) - { - /* If we just call convert_value_from_python for this type, - we won't know who owns the result. For this one case we - need to copy the resulting value. */ - v = value_object_to_value (py_v); - v = value_copy (v); - } - else - v = convert_value_from_python (py_v); + v = convert_value_from_python (py_v); /* TODO: This assume the name of the i-th child never changes. */ -- 2.30.2