* varobj.c (update_dynamic_varobj_children): Don't use
authorTom Tromey <tromey@redhat.com>
Thu, 13 Aug 2009 18:39:20 +0000 (18:39 +0000)
committerTom Tromey <tromey@redhat.com>
Thu, 13 Aug 2009 18:39:20 +0000 (18:39 +0000)
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.

gdb/ChangeLog
gdb/python/python-value.c
gdb/python/python.h
gdb/value.c
gdb/value.h
gdb/varobj.c

index 0dd69cbeeb87c3e641ee1c34fceabfebddfd9e28..bdcafe6a518f0d8462b1d98ca8ac8ff69d69a4d9 100644 (file)
@@ -1,3 +1,27 @@
+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.
+
 2009-08-13  Pedro Alves  <pedro@codesourcery.com>
 
        * remote.c (remote_pid_to_str): If printing a process id and we
index dd3c919786cf02b69ba3ff2125f32abd748f4679..c73c916f058357d40454ed1e3532499054eb61c1 100644 (file)
 #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 */
index 33b0437bd709ca65ee113a66989a17a7ad56c6d2..e97018090c5c0494c4e92b5e358897e69feb62be 100644 (file)
@@ -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 */
index 65a5aa93745ef21b99a9c3f3efda05a1ddccf283..97f236c5e9d31776b3fc7185f83b8ba9da2c9849 100644 (file)
@@ -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);
 }
index 29ad783d429e955e904e8fec93e6eda325667ae8..6f6b756085f1e7c7aab3aba6c29391cfe1d0e02c 100644 (file)
@@ -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 *);
index 4a94988b5727cfe0827c3efe10b4c9eb54ee3968..48d4cfb7fed9b6950caf5514d4f256105a10127c 100644 (file)
@@ -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.  */