OSDN Git Service

PR python/12533:
authortromey <tromey>
Thu, 22 Dec 2011 19:51:09 +0000 (19:51 +0000)
committertromey <tromey>
Thu, 22 Dec 2011 19:51:09 +0000 (19:51 +0000)
* value.h (release_value_or_incref): Declare.
* value.c (struct value) <released>: New field.
(free_all_values, release_value, value_release_to_mark): Update
'released'.
(release_value_or_incref): New function.
* python/py-value.c (valpy_new): Use release_value_or_incref.
(value_to_value_object): Likewise.
* varobj.c (install_new_value): Move value_incref earlier.

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

index 6fa76d6..34634e2 100644 (file)
@@ -1,5 +1,17 @@
 2011-12-22  Tom Tromey  <tromey@redhat.com>
 
+       PR python/12533:
+       * value.h (release_value_or_incref): Declare.
+       * value.c (struct value) <released>: New field.
+       (free_all_values, release_value, value_release_to_mark): Update
+       'released'.
+       (release_value_or_incref): New function.
+       * python/py-value.c (valpy_new): Use release_value_or_incref.
+       (value_to_value_object): Likewise.
+       * varobj.c (install_new_value): Move value_incref earlier.
+
+2011-12-22  Tom Tromey  <tromey@redhat.com>
+
        * value.c (struct value) <modifiable, lazy, optimized_out,
        initialized, stack>: Now bitfields.  Move to top.
        <reference_count>: Move earlier.
index 05e592f..04e355a 100644 (file)
@@ -150,7 +150,7 @@ valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
     }
 
   value_obj->value = value;
-  value_incref (value);
+  release_value_or_incref (value);
   value_obj->address = NULL;
   value_obj->type = NULL;
   value_obj->dynamic_type = NULL;
@@ -1123,7 +1123,7 @@ value_to_value_object (struct value *val)
   if (val_obj != NULL)
     {
       val_obj->value = val;
-      value_incref (val);
+      release_value_or_incref (val);
       val_obj->address = NULL;
       val_obj->type = NULL;
       val_obj->dynamic_type = NULL;
index b0aa415..d02bc27 100644 (file)
@@ -208,6 +208,9 @@ struct value
      used instead of read_memory to enable extra caching.  */
   unsigned int stack : 1;
 
+  /* If the value has been released.  */
+  unsigned int released : 1;
+
   /* Location of value (if lval).  */
   union
   {
@@ -1210,6 +1213,7 @@ value_free_to_mark (struct value *mark)
   for (val = all_values; val && val != mark; val = next)
     {
       next = val->next;
+      val->released = 1;
       value_free (val);
     }
   all_values = val;
@@ -1228,6 +1232,7 @@ free_all_values (void)
   for (val = all_values; val; val = next)
     {
       next = val->next;
+      val->released = 1;
       value_free (val);
     }
 
@@ -1260,6 +1265,7 @@ release_value (struct value *val)
     {
       all_values = val->next;
       val->next = NULL;
+      val->released = 1;
       return;
     }
 
@@ -1269,11 +1275,26 @@ release_value (struct value *val)
        {
          v->next = val->next;
          val->next = NULL;
+         val->released = 1;
          break;
        }
     }
 }
 
+/* If the value is not already released, release it.
+   If the value is already released, increment its reference count.
+   That is, this function ensures that the value is released from the
+   value chain and that the caller owns a reference to it.  */
+
+void
+release_value_or_incref (struct value *val)
+{
+  if (val->released)
+    value_incref (val);
+  else
+    release_value (val);
+}
+
 /* Release all values up to mark  */
 struct value *
 value_release_to_mark (struct value *mark)
@@ -1282,12 +1303,15 @@ value_release_to_mark (struct value *mark)
   struct value *next;
 
   for (val = next = all_values; next; next = next->next)
-    if (next->next == mark)
-      {
-       all_values = next->next;
-       next->next = NULL;
-       return val;
-      }
+    {
+      if (next->next == mark)
+       {
+         all_values = next->next;
+         next->next = NULL;
+         return val;
+       }
+      next->released = 1;
+    }
   all_values = 0;
   return val;
 }
index d2c58ec..167847f 100644 (file)
@@ -772,6 +772,8 @@ extern void free_value_chain (struct value *v);
 
 extern void release_value (struct value *val);
 
+extern void release_value_or_incref (struct value *val);
+
 extern int record_latest_value (struct value *val);
 
 extern void modify_field (struct type *type, gdb_byte *addr,
index 7c68a93..0d5987c 100644 (file)
@@ -1604,6 +1604,10 @@ install_new_value (struct varobj *var, struct value *value, int initial)
        }
     }
 
+  /* Get a reference now, before possibly passing it to any Python
+     code that might release it.  */
+  if (value != NULL)
+    value_incref (value);
 
   /* Below, we'll be comparing string rendering of old and new
      values.  Don't get string rendering if the value is
@@ -1671,8 +1675,6 @@ install_new_value (struct varobj *var, struct value *value, int initial)
   if (var->value != NULL && var->value != value)
     value_free (var->value);
   var->value = value;
-  if (value != NULL)
-    value_incref (value);
   if (value && value_lazy (value) && intentionally_not_fetched)
     var->not_fetched = 1;
   else