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.
This commit is contained in:
Tom Tromey 2011-12-22 19:51:10 +00:00
parent 87784a4754
commit e848a8a515
5 changed files with 50 additions and 10 deletions

View File

@ -1,3 +1,15 @@
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,

View 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;

View 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;
}

View 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,

View 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