This is the mail archive of the archer@sourceware.org mailing list for the Archer project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[python] minor python-value fixes


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  <tromey@redhat.com>

	* 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.
	<next, prev>: 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.  */
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]