summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2011-12-22 19:51:09 +0000
committerTom Tromey <tromey@redhat.com>2011-12-22 19:51:09 +0000
commitdbe5eff289dde3ca4b8e603e753004477fd712e7 (patch)
tree04564a73f915fd6fdb7577f374e07d775a3424eb
parent93f66bbd89f354e4e91b54e0c840656d818b5a45 (diff)
downloadgdb-dbe5eff289dde3ca4b8e603e753004477fd712e7.tar.gz
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.
-rw-r--r--gdb/ChangeLog12
-rw-r--r--gdb/python/py-value.c4
-rw-r--r--gdb/value.c36
-rw-r--r--gdb/value.h2
-rw-r--r--gdb/varobj.c6
5 files changed, 50 insertions, 10 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6fa76d67c5f..34634e2fe63 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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.
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 05e592f12e0..04e355ae697 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -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;
diff --git a/gdb/value.c b/gdb/value.c
index b0aa415fc75..d02bc278d53 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -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;
}
diff --git a/gdb/value.h b/gdb/value.h
index d2c58ecf044..167847fcc14 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -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,
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 7c68a93bb03..0d5987cb0b7 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -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