Add scoped_value_mark

This adds a scoped_value_mark class, that records the value mark in
the constructor and then calls value_free_to_mark in the destructor.
It then updates various spots in gdb to use this class, rather than a
cleanup.

It would be better overall to replace "struct value *" with a
shared_ptr, maybe eliminating the need for this class (watchpoints
would perhaps need some new mechanism as well).  However, that's
difficult to do.

2017-01-10  Tom Tromey  <tom@tromey.com>

	* python/py-value.c (valpy_dereference, valpy_referenced_value)
	(valpy_reference_value, valpy_const_value, valpy_get_address)
	(valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast)
	(valpy_getitem, valpy_call, valpy_binop_throw, valpy_negative)
	(valpy_absolute, valpy_richcompare_throw): Use scoped_value_mark.
	* dwarf2loc.c (dwarf2_loc_desc_get_symbol_read_needs): Use
	scoped_value_mark.
	* dwarf2-frame.c (execute_stack_op): Use scoped_value_mark.
	* value.h (scoped_value_mark): New class.
This commit is contained in:
Tom Tromey 2016-11-21 18:02:11 -07:00
parent 906768f970
commit eb11506932
5 changed files with 55 additions and 54 deletions

View file

@ -1,3 +1,15 @@
2017-01-10 Tom Tromey <tom@tromey.com>
* python/py-value.c (valpy_dereference, valpy_referenced_value)
(valpy_reference_value, valpy_const_value, valpy_get_address)
(valpy_get_dynamic_type, valpy_lazy_string, valpy_do_cast)
(valpy_getitem, valpy_call, valpy_binop_throw, valpy_negative)
(valpy_absolute, valpy_richcompare_throw): Use scoped_value_mark.
* dwarf2loc.c (dwarf2_loc_desc_get_symbol_read_needs): Use
scoped_value_mark.
* dwarf2-frame.c (execute_stack_op): Use scoped_value_mark.
* value.h (scoped_value_mark): New class.
2017-01-10 Tom Tromey <tom@tromey.com> 2017-01-10 Tom Tromey <tom@tromey.com>
* dwarf2read.c (dwarf2_build_psymtabs): Use psymtab_discarder. * dwarf2read.c (dwarf2_build_psymtabs): Use psymtab_discarder.

View file

@ -403,10 +403,9 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
CORE_ADDR initial, int initial_in_stack_memory) CORE_ADDR initial, int initial_in_stack_memory)
{ {
CORE_ADDR result; CORE_ADDR result;
struct cleanup *old_chain;
dwarf_expr_executor ctx; dwarf_expr_executor ctx;
old_chain = make_cleanup_value_free_to_mark (value_mark ()); scoped_value_mark free_values;
ctx.this_frame = this_frame; ctx.this_frame = this_frame;
ctx.gdbarch = get_frame_arch (this_frame); ctx.gdbarch = get_frame_arch (this_frame);
@ -430,8 +429,6 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
Not implemented: computing unwound register using explicit value operator")); Not implemented: computing unwound register using explicit value operator"));
} }
do_cleanups (old_chain);
return result; return result;
} }

View file

@ -2790,16 +2790,14 @@ dwarf2_loc_desc_get_symbol_read_needs (const gdb_byte *data, size_t size,
struct dwarf2_per_cu_data *per_cu) struct dwarf2_per_cu_data *per_cu)
{ {
int in_reg; int in_reg;
struct cleanup *old_chain;
struct objfile *objfile = dwarf2_per_cu_objfile (per_cu); struct objfile *objfile = dwarf2_per_cu_objfile (per_cu);
scoped_value_mark free_values;
symbol_needs_eval_context ctx; symbol_needs_eval_context ctx;
ctx.needs = SYMBOL_NEEDS_NONE; ctx.needs = SYMBOL_NEEDS_NONE;
ctx.per_cu = per_cu; ctx.per_cu = per_cu;
old_chain = make_cleanup_value_free_to_mark (value_mark ());
ctx.gdbarch = get_objfile_arch (objfile); ctx.gdbarch = get_objfile_arch (objfile);
ctx.addr_size = dwarf2_per_cu_addr_size (per_cu); ctx.addr_size = dwarf2_per_cu_addr_size (per_cu);
ctx.ref_addr_size = dwarf2_per_cu_ref_addr_size (per_cu); ctx.ref_addr_size = dwarf2_per_cu_ref_addr_size (per_cu);
@ -2820,8 +2818,6 @@ dwarf2_loc_desc_get_symbol_read_needs (const gdb_byte *data, size_t size,
in_reg = 1; in_reg = 1;
} }
do_cleanups (old_chain);
if (in_reg) if (in_reg)
ctx.needs = SYMBOL_NEEDS_FRAME; ctx.needs = SYMBOL_NEEDS_FRAME;
return ctx.needs; return ctx.needs;

View file

@ -178,11 +178,10 @@ valpy_dereference (PyObject *self, PyObject *args)
TRY TRY
{ {
struct value *res_val; struct value *res_val;
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); scoped_value_mark free_values;
res_val = value_ind (((value_object *) self)->value); res_val = value_ind (((value_object *) self)->value);
result = value_to_value_object (res_val); result = value_to_value_object (res_val);
do_cleanups (cleanup);
} }
CATCH (except, RETURN_MASK_ALL) CATCH (except, RETURN_MASK_ALL)
{ {
@ -209,7 +208,7 @@ valpy_referenced_value (PyObject *self, PyObject *args)
TRY TRY
{ {
struct value *self_val, *res_val; struct value *self_val, *res_val;
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); scoped_value_mark free_values;
self_val = ((value_object *) self)->value; self_val = ((value_object *) self)->value;
switch (TYPE_CODE (check_typedef (value_type (self_val)))) switch (TYPE_CODE (check_typedef (value_type (self_val))))
@ -226,7 +225,6 @@ valpy_referenced_value (PyObject *self, PyObject *args)
} }
result = value_to_value_object (res_val); result = value_to_value_object (res_val);
do_cleanups (cleanup);
} }
CATCH (except, RETURN_MASK_ALL) CATCH (except, RETURN_MASK_ALL)
{ {
@ -247,12 +245,10 @@ valpy_reference_value (PyObject *self, PyObject *args)
TRY TRY
{ {
struct value *self_val; struct value *self_val;
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); scoped_value_mark free_values;
self_val = ((value_object *) self)->value; self_val = ((value_object *) self)->value;
result = value_to_value_object (value_ref (self_val)); result = value_to_value_object (value_ref (self_val));
do_cleanups (cleanup);
} }
CATCH (except, RETURN_MASK_ALL) CATCH (except, RETURN_MASK_ALL)
{ {
@ -273,13 +269,11 @@ valpy_const_value (PyObject *self, PyObject *args)
TRY TRY
{ {
struct value *self_val, *res_val; struct value *self_val, *res_val;
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); scoped_value_mark free_values;
self_val = ((value_object *) self)->value; self_val = ((value_object *) self)->value;
res_val = make_cv_value (1, 0, self_val); res_val = make_cv_value (1, 0, self_val);
result = value_to_value_object (res_val); result = value_to_value_object (res_val);
do_cleanups (cleanup);
} }
CATCH (except, RETURN_MASK_ALL) CATCH (except, RETURN_MASK_ALL)
{ {
@ -301,12 +295,10 @@ valpy_get_address (PyObject *self, void *closure)
TRY TRY
{ {
struct value *res_val; struct value *res_val;
struct cleanup *cleanup scoped_value_mark free_values;
= make_cleanup_value_free_to_mark (value_mark ());
res_val = value_addr (val_obj->value); res_val = value_addr (val_obj->value);
val_obj->address = value_to_value_object (res_val); val_obj->address = value_to_value_object (res_val);
do_cleanups (cleanup);
} }
CATCH (except, RETURN_MASK_ALL) CATCH (except, RETURN_MASK_ALL)
{ {
@ -354,7 +346,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
TRY TRY
{ {
struct value *val = obj->value; struct value *val = obj->value;
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); scoped_value_mark free_values;
type = value_type (val); type = value_type (val);
type = check_typedef (type); type = check_typedef (type);
@ -387,8 +379,6 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
/* Re-use object's static type. */ /* Re-use object's static type. */
type = NULL; type = NULL;
} }
do_cleanups (cleanup);
} }
CATCH (except, RETURN_MASK_ALL) CATCH (except, RETURN_MASK_ALL)
{ {
@ -428,7 +418,7 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
TRY TRY
{ {
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); scoped_value_mark free_values;
if (TYPE_CODE (value_type (value)) == TYPE_CODE_PTR) if (TYPE_CODE (value_type (value)) == TYPE_CODE_PTR)
value = value_ind (value); value = value_ind (value);
@ -436,8 +426,6 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
str_obj = gdbpy_create_lazy_string_object (value_address (value), length, str_obj = gdbpy_create_lazy_string_object (value_address (value), length,
user_encoding, user_encoding,
value_type (value)); value_type (value));
do_cleanups (cleanup);
} }
CATCH (except, RETURN_MASK_ALL) CATCH (except, RETURN_MASK_ALL)
{ {
@ -514,7 +502,7 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
{ {
struct value *val = ((value_object *) self)->value; struct value *val = ((value_object *) self)->value;
struct value *res_val; struct value *res_val;
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); scoped_value_mark free_values;
if (op == UNOP_DYNAMIC_CAST) if (op == UNOP_DYNAMIC_CAST)
res_val = value_dynamic_cast (type, val); res_val = value_dynamic_cast (type, val);
@ -527,7 +515,6 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
} }
result = value_to_value_object (res_val); result = value_to_value_object (res_val);
do_cleanups (cleanup);
} }
CATCH (except, RETURN_MASK_ALL) CATCH (except, RETURN_MASK_ALL)
{ {
@ -737,8 +724,8 @@ valpy_getitem (PyObject *self, PyObject *key)
TRY TRY
{ {
struct value *tmp = self_value->value; struct value *tmp = self_value->value;
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
struct value *res_val = NULL; struct value *res_val = NULL;
scoped_value_mark free_values;
if (field) if (field)
res_val = value_struct_elt (&tmp, NULL, field.get (), NULL, res_val = value_struct_elt (&tmp, NULL, field.get (), NULL,
@ -783,7 +770,6 @@ valpy_getitem (PyObject *self, PyObject *key)
if (res_val) if (res_val)
result = value_to_value_object (res_val); result = value_to_value_object (res_val);
do_cleanups (cleanup);
} }
CATCH (ex, RETURN_MASK_ALL) CATCH (ex, RETURN_MASK_ALL)
{ {
@ -861,12 +847,11 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
TRY TRY
{ {
struct cleanup *cleanup = make_cleanup_value_free_to_mark (mark); scoped_value_mark free_values;
struct value *return_value; struct value *return_value;
return_value = call_function_by_hand (function, args_count, vargs); return_value = call_function_by_hand (function, args_count, vargs);
result = value_to_value_object (return_value); result = value_to_value_object (return_value);
do_cleanups (cleanup);
} }
CATCH (except, RETURN_MASK_ALL) CATCH (except, RETURN_MASK_ALL)
{ {
@ -1014,11 +999,12 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
PyObject *result = NULL; PyObject *result = NULL;
struct value *arg1, *arg2; struct value *arg1, *arg2;
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
struct value *res_val = NULL; struct value *res_val = NULL;
enum exp_opcode op = OP_NULL; enum exp_opcode op = OP_NULL;
int handled = 0; int handled = 0;
scoped_value_mark free_values;
/* If the gdb.Value object is the second operand, then it will be /* If the gdb.Value object is the second operand, then it will be
passed to us as the OTHER argument, and SELF will be an entirely passed to us as the OTHER argument, and SELF will be an entirely
different kind of object, altogether. Because of this, we can't different kind of object, altogether. Because of this, we can't
@ -1026,17 +1012,11 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
python as well. */ python as well. */
arg1 = convert_value_from_python (self); arg1 = convert_value_from_python (self);
if (arg1 == NULL) if (arg1 == NULL)
{
do_cleanups (cleanup);
return NULL; return NULL;
}
arg2 = convert_value_from_python (other); arg2 = convert_value_from_python (other);
if (arg2 == NULL) if (arg2 == NULL)
{
do_cleanups (cleanup);
return NULL; return NULL;
}
switch (opcode) switch (opcode)
{ {
@ -1130,7 +1110,6 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
if (res_val) if (res_val)
result = value_to_value_object (res_val); result = value_to_value_object (res_val);
do_cleanups (cleanup);
return result; return result;
} }
@ -1209,12 +1188,11 @@ valpy_negative (PyObject *self)
TRY TRY
{ {
/* Perhaps overkill, but consistency has some virtue. */ /* Perhaps overkill, but consistency has some virtue. */
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); scoped_value_mark free_values;
struct value *val; struct value *val;
val = value_neg (((value_object *) self)->value); val = value_neg (((value_object *) self)->value);
result = value_to_value_object (val); result = value_to_value_object (val);
do_cleanups (cleanup);
} }
CATCH (except, RETURN_MASK_ALL) CATCH (except, RETURN_MASK_ALL)
{ {
@ -1239,12 +1217,10 @@ valpy_absolute (PyObject *self)
TRY TRY
{ {
struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ()); scoped_value_mark free_values;
if (value_less (value, value_zero (value_type (value), not_lval))) if (value_less (value, value_zero (value_type (value), not_lval)))
isabs = 0; isabs = 0;
do_cleanups (cleanup);
} }
CATCH (except, RETURN_MASK_ALL) CATCH (except, RETURN_MASK_ALL)
{ {
@ -1362,15 +1338,14 @@ valpy_richcompare_throw (PyObject *self, PyObject *other, int op)
int result; int result;
struct value *value_other; struct value *value_other;
struct value *value_self; struct value *value_self;
struct value *mark = value_mark ();
struct cleanup *cleanup; struct cleanup *cleanup;
scoped_value_mark free_values;
value_other = convert_value_from_python (other); value_other = convert_value_from_python (other);
if (value_other == NULL) if (value_other == NULL)
return -1; return -1;
cleanup = make_cleanup_value_free_to_mark (mark);
value_self = ((value_object *) self)->value; value_self = ((value_object *) self)->value;
switch (op) switch (op)
@ -1403,7 +1378,6 @@ valpy_richcompare_throw (PyObject *self, PyObject *other, int op)
break; break;
} }
do_cleanups (cleanup);
return result; return result;
} }

View file

@ -714,6 +714,28 @@ extern struct value *value_mark (void);
extern void value_free_to_mark (const struct value *mark); extern void value_free_to_mark (const struct value *mark);
/* A helper class that uses value_mark at construction time and calls
value_free_to_mark in the destructor. This is used to clear out
temporary values created during the lifetime of this object. */
class scoped_value_mark
{
public:
scoped_value_mark ()
: m_value (value_mark ())
{
}
~scoped_value_mark ()
{
value_free_to_mark (m_value);
}
private:
const struct value *m_value;
};
extern struct value *value_cstring (const char *ptr, ssize_t len, extern struct value *value_cstring (const char *ptr, ssize_t len,
struct type *char_type); struct type *char_type);
extern struct value *value_string (const char *ptr, ssize_t len, extern struct value *value_string (const char *ptr, ssize_t len,