diff options
author | Tom Tromey <tromey@redhat.com> | 2011-12-22 19:51:10 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2011-12-22 19:51:10 +0000 |
commit | e848a8a515f6a2a2b036933ed430c0aa6dbc2fde (patch) | |
tree | f9a9baa6df49f8417c91191f17e933c9a05d996e | |
parent | * value.c (struct value) <modifiable, lazy, optimized_out, (diff) | |
download | binutils-gdb-e848a8a515f6a2a2b036933ed430c0aa6dbc2fde.tar.gz binutils-gdb-e848a8a515f6a2a2b036933ed430c0aa6dbc2fde.tar.bz2 binutils-gdb-e848a8a515f6a2a2b036933ed430c0aa6dbc2fde.zip |
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/ChangeLog | 12 | ||||
-rw-r--r-- | gdb/python/py-value.c | 4 | ||||
-rw-r--r-- | gdb/value.c | 36 | ||||
-rw-r--r-- | gdb/value.h | 2 | ||||
-rw-r--r-- | gdb/varobj.c | 6 |
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 |