From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6716 invoked by alias); 13 Aug 2009 18:25:05 -0000 Mailing-List: contact archer-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: List-Id: Received: (qmail 6263 invoked by uid 22791); 13 Aug 2009 18:25:00 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS X-Spam-Check-By: sourceware.org To: Project Archer Subject: [python] minor python-value fixes From: Tom Tromey Reply-To: Tom Tromey Date: Thu, 13 Aug 2009 18:25:00 -0000 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2009-q3/txt/msg00127.txt.bz2 I'm checking this in on the python branch. This changes Value to use a doubly-linked list. This makes Value destruction perform better. This also fixes a buglet in convert_value_from_python that I noticed when trying to merge some of this upstream. convert_value_from_python has to always return something on the value chain. Now, this is not ideal, since it means a call to value_copy. Fixing this, though, is rather more involved. Finally, this removes some unused value.c functions that were introduced for an earlier version of this code. I'll be pushing all this upstream shortly; the code will look pretty similar now. Tom 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. diff --git a/gdb/python/python-value.c b/gdb/python/python-value.c index dd3c919..c73c916 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 33b0437..e970180 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 65a5aa9..97f236c 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 29ad783..6f6b756 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 4a94988..48d4cfb 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. */