Introduce a gdb_ref_ptr specialization for struct value

struct value is internally reference counted and so, while it also has
some ownership rules unique to it, it makes sense to use a gdb_ref_ptr
when managing it automatically.

This patch removes the existing unique_ptr specialization in favor of
a reference-counted pointer.  It also introduces two other
clarifications:

1. Rename value_free to value_decref, which I think is more in line
   with what the function actually does; and

2. Change release_value to return a gdb_ref_ptr.  This change allows
   us to remove the confusing release_value_or_incref function,
   primarily by making it much simpler to reason about the result of
   release_value.

gdb/ChangeLog
2018-04-06  Tom Tromey  <tom@tromey.com>

	* varobj.c (varobj_clear_saved_item)
	(update_dynamic_varobj_children, install_new_value, ~varobj):
	Update.
	* value.h (value_incref): Move declaration earlier.
	(value_decref): Rename from value_free.
	(struct value_ref_policy): New.
	(value_ref_ptr): New typedef.
	(struct value_deleter): Remove.
	(gdb_value_up): Remove typedef.
	(release_value): Change return type.
	(release_value_or_incref): Remove.
	* value.c (set_value_parent): Update.
	(value_incref): Change return type.
	(value_decref): Rename from value_free.
	(value_free_to_mark, free_all_values, free_value_chain): Update.
	(release_value): Return value_ref_ptr.
	(release_value_or_incref): Remove.
	(record_latest_value, set_internalvar, clear_internalvar):
	Update.
	* stack.c (info_frame_command): Don't call value_free.
	* python/py-value.c (valpy_dealloc, valpy_new)
	(value_to_value_object): Update.
	* printcmd.c (do_examine): Update.
	* opencl-lang.c (lval_func_free_closure): Update.
	* mi/mi-main.c (register_changed_p): Don't call value_free.
	* mep-tdep.c (mep_frame_prev_register): Don't call value_free.
	* m88k-tdep.c (m88k_frame_prev_register): Don't call value_free.
	* m68hc11-tdep.c (m68hc11_frame_prev_register): Don't call
	value_free.
	* guile/scm-value.c (vlscm_free_value_smob)
	(vlscm_scm_from_value): Update.
	* frame.c (frame_register_unwind, frame_unwind_register_signed)
	(frame_unwind_register_unsigned, get_frame_register_bytes)
	(put_frame_register_bytes): Don't call value_free.
	* findvar.c (address_from_register): Don't call value_free.
	* dwarf2read.c (dwarf2_compute_name): Don't call value_free.
	* dwarf2loc.c (entry_data_value_free_closure)
	(value_of_dwarf_reg_entry, free_pieced_value_closure)
	(dwarf2_evaluate_loc_desc_full): Update.
	* breakpoint.c (update_watchpoint, breakpoint_init_inferior)
	(~bpstats, bpstats, bpstat_clear_actions, watchpoint_check)
	(~watchpoint, watch_command_1)
	(invalidate_bp_value_on_memory_change): Update.
	* alpha-tdep.c (alpha_register_to_value): Don't call value_free.
This commit is contained in:
Tom Tromey
2018-04-03 17:45:21 -06:00
parent 7f8a5d38ed
commit 22bc8444e6
19 changed files with 136 additions and 114 deletions

View File

@@ -1740,7 +1740,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
no longer relevant. We don't want to report a watchpoint hit
to the user when the old value and the new value may actually
be completely different objects. */
value_free (b->val);
value_decref (b->val);
b->val = NULL;
b->val_valid = 0;
@@ -1795,7 +1795,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
{
v = extract_bitfield_from_watchpoint_value (b, v);
if (v != NULL)
release_value (v);
release_value (v).release ();
}
b->val = v;
b->val_valid = 1;
@@ -1971,7 +1971,7 @@ update_watchpoint (struct watchpoint *b, int reparse)
{
next = value_next (v);
if (v != b->val)
value_free (v);
value_decref (v);
}
/* If a software watchpoint is not watching any memory, then the
@@ -3952,7 +3952,7 @@ breakpoint_init_inferior (enum inf_context context)
/* Reset val field to force reread of starting value in
insert_breakpoints. */
if (w->val)
value_free (w->val);
value_decref (w->val);
w->val = NULL;
w->val_valid = 0;
}
@@ -4200,7 +4200,7 @@ is_catchpoint (struct breakpoint *ep)
bpstats::~bpstats ()
{
if (old_val != NULL)
value_free (old_val);
value_decref (old_val);
if (bp_location_at != NULL)
decref_bp_location (&bp_location_at);
}
@@ -4237,10 +4237,7 @@ bpstats::bpstats (const bpstats &other)
print_it (other.print_it)
{
if (old_val != NULL)
{
old_val = value_copy (old_val);
release_value (old_val);
}
old_val = release_value (value_copy (old_val)).release ();
incref_bp_location (bp_location_at);
}
@@ -4364,7 +4361,7 @@ bpstat_clear_actions (void)
if (bs->old_val != NULL)
{
value_free (bs->old_val);
value_decref (bs->old_val);
bs->old_val = NULL;
}
}
@@ -4942,7 +4939,7 @@ watchpoint_check (bpstat bs)
{
if (new_val != NULL)
{
release_value (new_val);
release_value (new_val).release ();
value_free_to_mark (mark);
}
bs->old_val = b->val;
@@ -10102,7 +10099,7 @@ watchpoint::~watchpoint ()
{
xfree (this->exp_string);
xfree (this->exp_string_reparse);
value_free (this->val);
value_decref (this->val);
}
/* Implement the "re_set" breakpoint_ops method for watchpoints. */
@@ -10725,8 +10722,7 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
int ret;
exp_valid_block = NULL;
val = value_addr (result);
release_value (val);
val = release_value (value_addr (result)).release ();
value_free_to_mark (mark);
if (use_mask)
@@ -10740,7 +10736,7 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
}
}
else if (val != NULL)
release_value (val);
release_value (val).release ();
tok = skip_spaces (arg);
end_tok = skip_to_space (tok);
@@ -14546,7 +14542,7 @@ invalidate_bp_value_on_memory_change (struct inferior *inferior,
&& loc->address + loc->length > addr
&& addr + len > loc->address)
{
value_free (wp->val);
value_decref (wp->val);
wp->val = NULL;
wp->val_valid = 0;
}