Initial conversion of dwarf_expr_ctx

This is the first step in the conversion of dwarf_expr_ctx to a C++
class.  This conversion is done in steps to make the patches, and the
reviews, a bit simpler.  This patch changes dwarf_expr_ctx to be
stack-allocated and removes the associated cleanup.

2016-10-21  Tom Tromey  <tom@tromey.com>

	* dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Stack-allocate
	dwarf_expr_context.  Remove cleanups.
	(dwarf2_locexpr_baton_eval)
	(dwarf2_loc_desc_get_symbol_read_needs):  Likewise.
	* dwarf2expr.h (dwarf_expr_context, ~dwarf_expr_context): Add
	constructors and destructors.
	(new_dwarf_expr_context, free_dwarf_expr_context)
	(make_cleanup_free_dwarf_expr_context): Don't declare.
	* dwarf2-frame.c (execute_stack_op): Stack-allocate
	dwarf_expr_context.  Remove cleanups.
	(dwarf_expr_context): Rename from new_dwarf_expr_context.  Turn
	into constructor.
	(free_dwarf_expr_context, free_dwarf_expr_context_cleanup):
	Remove.
	(~dwarf_expr_context): Rename from
	make_cleanup_free_dwarf_expr_context.  Turn into destructor.
This commit is contained in:
Tom Tromey 2016-09-25 16:28:03 -06:00
parent 5841433461
commit 718b962660
5 changed files with 110 additions and 117 deletions

View File

@ -1,3 +1,22 @@
2016-10-21 Tom Tromey <tom@tromey.com>
* dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Stack-allocate
dwarf_expr_context. Remove cleanups.
(dwarf2_locexpr_baton_eval)
(dwarf2_loc_desc_get_symbol_read_needs): Likewise.
* dwarf2expr.h (dwarf_expr_context, ~dwarf_expr_context): Add
constructors and destructors.
(new_dwarf_expr_context, free_dwarf_expr_context)
(make_cleanup_free_dwarf_expr_context): Don't declare.
* dwarf2-frame.c (execute_stack_op): Stack-allocate
dwarf_expr_context. Remove cleanups.
(dwarf_expr_context): Rename from new_dwarf_expr_context. Turn
into constructor.
(free_dwarf_expr_context, free_dwarf_expr_context_cleanup):
Remove.
(~dwarf_expr_context): Rename from
make_cleanup_free_dwarf_expr_context. Turn into destructor.
2016-10-21 Tom Tromey <tom@tromey.com> 2016-10-21 Tom Tromey <tom@tromey.com>
* dwarf2loc.c: Include <vector>. * dwarf2loc.c: Include <vector>.

View File

@ -369,29 +369,27 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
CORE_ADDR offset, struct frame_info *this_frame, CORE_ADDR offset, struct frame_info *this_frame,
CORE_ADDR initial, int initial_in_stack_memory) CORE_ADDR initial, int initial_in_stack_memory)
{ {
struct dwarf_expr_context *ctx;
CORE_ADDR result; CORE_ADDR result;
struct cleanup *old_chain; struct cleanup *old_chain;
ctx = new_dwarf_expr_context (); dwarf_expr_context ctx;
old_chain = make_cleanup_free_dwarf_expr_context (ctx); old_chain = make_cleanup_value_free_to_mark (value_mark ());
make_cleanup_value_free_to_mark (value_mark ());
ctx->gdbarch = get_frame_arch (this_frame); ctx.gdbarch = get_frame_arch (this_frame);
ctx->addr_size = addr_size; ctx.addr_size = addr_size;
ctx->ref_addr_size = -1; ctx.ref_addr_size = -1;
ctx->offset = offset; ctx.offset = offset;
ctx->baton = this_frame; ctx.baton = this_frame;
ctx->funcs = &dwarf2_frame_ctx_funcs; ctx.funcs = &dwarf2_frame_ctx_funcs;
dwarf_expr_push_address (ctx, initial, initial_in_stack_memory); dwarf_expr_push_address (&ctx, initial, initial_in_stack_memory);
dwarf_expr_eval (ctx, exp, len); dwarf_expr_eval (&ctx, exp, len);
if (ctx->location == DWARF_VALUE_MEMORY) if (ctx.location == DWARF_VALUE_MEMORY)
result = dwarf_expr_fetch_address (ctx, 0); result = dwarf_expr_fetch_address (&ctx, 0);
else if (ctx->location == DWARF_VALUE_REGISTER) else if (ctx.location == DWARF_VALUE_REGISTER)
result = read_addr_from_reg (this_frame, result = read_addr_from_reg (this_frame,
value_as_long (dwarf_expr_fetch (ctx, 0))); value_as_long (dwarf_expr_fetch (&ctx, 0)));
else else
{ {
/* This is actually invalid DWARF, but if we ever do run across /* This is actually invalid DWARF, but if we ever do run across

View File

@ -91,45 +91,32 @@ dwarf_expr_address_type (struct dwarf_expr_context *ctx)
/* Create a new context for the expression evaluator. */ /* Create a new context for the expression evaluator. */
struct dwarf_expr_context * dwarf_expr_context::dwarf_expr_context ()
new_dwarf_expr_context (void) : stack (NULL),
stack_len (0),
stack_allocated (10),
gdbarch (NULL),
addr_size (0),
ref_addr_size (0),
offset (0),
recursion_depth (0),
max_recursion_depth (0x100),
location (DWARF_VALUE_MEMORY),
len (0),
data (NULL),
initialized (0),
num_pieces (0),
pieces (NULL)
{ {
struct dwarf_expr_context *retval; this->stack = XNEWVEC (struct dwarf_stack_value, this->stack_allocated);
retval = XCNEW (struct dwarf_expr_context);
retval->stack_len = 0;
retval->stack_allocated = 10;
retval->stack = XNEWVEC (struct dwarf_stack_value, retval->stack_allocated);
retval->num_pieces = 0;
retval->pieces = 0;
retval->max_recursion_depth = 0x100;
return retval;
} }
/* Release the memory allocated to CTX. */ /* Clean up a dwarf_expr_context. */
void dwarf_expr_context::~dwarf_expr_context ()
free_dwarf_expr_context (struct dwarf_expr_context *ctx)
{ {
xfree (ctx->stack); xfree (this->stack);
xfree (ctx->pieces); xfree (this->pieces);
xfree (ctx);
}
/* Helper for make_cleanup_free_dwarf_expr_context. */
static void
free_dwarf_expr_context_cleanup (void *arg)
{
free_dwarf_expr_context ((struct dwarf_expr_context *) arg);
}
/* Return a cleanup that calls free_dwarf_expr_context. */
struct cleanup *
make_cleanup_free_dwarf_expr_context (struct dwarf_expr_context *ctx)
{
return make_cleanup (free_dwarf_expr_context_cleanup, ctx);
} }
/* Expand the memory allocated to CTX's stack to contain at least /* Expand the memory allocated to CTX's stack to contain at least

View File

@ -130,6 +130,9 @@ struct dwarf_stack_value
its current state and its callbacks. */ its current state and its callbacks. */
struct dwarf_expr_context struct dwarf_expr_context
{ {
dwarf_expr_context ();
~dwarf_expr_context ();
/* The stack of values, allocated with xmalloc. */ /* The stack of values, allocated with xmalloc. */
struct dwarf_stack_value *stack; struct dwarf_stack_value *stack;
@ -250,11 +253,6 @@ struct dwarf_expr_piece
ULONGEST offset; ULONGEST offset;
}; };
struct dwarf_expr_context *new_dwarf_expr_context (void);
void free_dwarf_expr_context (struct dwarf_expr_context *ctx);
struct cleanup *
make_cleanup_free_dwarf_expr_context (struct dwarf_expr_context *ctx);
void dwarf_expr_push_address (struct dwarf_expr_context *ctx, void dwarf_expr_push_address (struct dwarf_expr_context *ctx,
CORE_ADDR value, CORE_ADDR value,
int in_stack_memory); int in_stack_memory);

View File

@ -2294,8 +2294,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
{ {
struct value *retval; struct value *retval;
struct dwarf_expr_baton baton; struct dwarf_expr_baton baton;
struct dwarf_expr_context *ctx; struct cleanup *value_chain;
struct cleanup *old_chain, *value_chain;
struct objfile *objfile = dwarf2_per_cu_objfile (per_cu); struct objfile *objfile = dwarf2_per_cu_objfile (per_cu);
if (byte_offset < 0) if (byte_offset < 0)
@ -2308,26 +2307,25 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
baton.per_cu = per_cu; baton.per_cu = per_cu;
baton.obj_address = 0; baton.obj_address = 0;
ctx = new_dwarf_expr_context (); dwarf_expr_context ctx;
old_chain = make_cleanup_free_dwarf_expr_context (ctx);
value_chain = make_cleanup_value_free_to_mark (value_mark ()); value_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);
ctx->offset = dwarf2_per_cu_text_offset (per_cu); ctx.offset = dwarf2_per_cu_text_offset (per_cu);
ctx->baton = &baton; ctx.baton = &baton;
ctx->funcs = &dwarf_expr_ctx_funcs; ctx.funcs = &dwarf_expr_ctx_funcs;
TRY TRY
{ {
dwarf_expr_eval (ctx, data, size); dwarf_expr_eval (&ctx, data, size);
} }
CATCH (ex, RETURN_MASK_ERROR) CATCH (ex, RETURN_MASK_ERROR)
{ {
if (ex.error == NOT_AVAILABLE_ERROR) if (ex.error == NOT_AVAILABLE_ERROR)
{ {
do_cleanups (old_chain); do_cleanups (value_chain);
retval = allocate_value (type); retval = allocate_value (type);
mark_value_bytes_unavailable (retval, 0, TYPE_LENGTH (type)); mark_value_bytes_unavailable (retval, 0, TYPE_LENGTH (type));
return retval; return retval;
@ -2336,7 +2334,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
{ {
if (entry_values_debug) if (entry_values_debug)
exception_print (gdb_stdout, ex); exception_print (gdb_stdout, ex);
do_cleanups (old_chain); do_cleanups (value_chain);
return allocate_optimized_out_value (type); return allocate_optimized_out_value (type);
} }
else else
@ -2344,20 +2342,20 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
} }
END_CATCH END_CATCH
if (ctx->num_pieces > 0) if (ctx.num_pieces > 0)
{ {
struct piece_closure *c; struct piece_closure *c;
struct frame_id frame_id = get_frame_id (frame); struct frame_id frame_id = get_frame_id (frame);
ULONGEST bit_size = 0; ULONGEST bit_size = 0;
int i; int i;
for (i = 0; i < ctx->num_pieces; ++i) for (i = 0; i < ctx.num_pieces; ++i)
bit_size += ctx->pieces[i].size; bit_size += ctx.pieces[i].size;
if (8 * (byte_offset + TYPE_LENGTH (type)) > bit_size) if (8 * (byte_offset + TYPE_LENGTH (type)) > bit_size)
invalid_synthetic_pointer (); invalid_synthetic_pointer ();
c = allocate_piece_closure (per_cu, ctx->num_pieces, ctx->pieces, c = allocate_piece_closure (per_cu, ctx.num_pieces, ctx.pieces,
ctx->addr_size); ctx.addr_size);
/* We must clean up the value chain after creating the piece /* We must clean up the value chain after creating the piece
closure but before allocating the result. */ closure but before allocating the result. */
do_cleanups (value_chain); do_cleanups (value_chain);
@ -2367,13 +2365,13 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
} }
else else
{ {
switch (ctx->location) switch (ctx.location)
{ {
case DWARF_VALUE_REGISTER: case DWARF_VALUE_REGISTER:
{ {
struct gdbarch *arch = get_frame_arch (frame); struct gdbarch *arch = get_frame_arch (frame);
int dwarf_regnum int dwarf_regnum
= longest_to_int (value_as_long (dwarf_expr_fetch (ctx, 0))); = longest_to_int (value_as_long (dwarf_expr_fetch (&ctx, 0)));
int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, dwarf_regnum); int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, dwarf_regnum);
if (byte_offset != 0) if (byte_offset != 0)
@ -2401,8 +2399,8 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
case DWARF_VALUE_MEMORY: case DWARF_VALUE_MEMORY:
{ {
struct type *ptr_type; struct type *ptr_type;
CORE_ADDR address = dwarf_expr_fetch_address (ctx, 0); CORE_ADDR address = dwarf_expr_fetch_address (&ctx, 0);
int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0); int in_stack_memory = dwarf_expr_fetch_in_stack_memory (&ctx, 0);
/* DW_OP_deref_size (and possibly other operations too) may /* DW_OP_deref_size (and possibly other operations too) may
create a pointer instead of an address. Ideally, the create a pointer instead of an address. Ideally, the
@ -2416,10 +2414,10 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
{ {
case TYPE_CODE_FUNC: case TYPE_CODE_FUNC:
case TYPE_CODE_METHOD: case TYPE_CODE_METHOD:
ptr_type = builtin_type (ctx->gdbarch)->builtin_func_ptr; ptr_type = builtin_type (ctx.gdbarch)->builtin_func_ptr;
break; break;
default: default:
ptr_type = builtin_type (ctx->gdbarch)->builtin_data_ptr; ptr_type = builtin_type (ctx.gdbarch)->builtin_data_ptr;
break; break;
} }
address = value_as_address (value_from_pointer (ptr_type, address)); address = value_as_address (value_from_pointer (ptr_type, address));
@ -2433,7 +2431,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
case DWARF_VALUE_STACK: case DWARF_VALUE_STACK:
{ {
struct value *value = dwarf_expr_fetch (ctx, 0); struct value *value = dwarf_expr_fetch (&ctx, 0);
gdb_byte *contents; gdb_byte *contents;
const gdb_byte *val_bytes; const gdb_byte *val_bytes;
size_t n = TYPE_LENGTH (value_type (value)); size_t n = TYPE_LENGTH (value_type (value));
@ -2470,7 +2468,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
{ {
bfd_byte *contents; bfd_byte *contents;
const bfd_byte *ldata; const bfd_byte *ldata;
size_t n = ctx->len; size_t n = ctx.len;
if (byte_offset + TYPE_LENGTH (type) > n) if (byte_offset + TYPE_LENGTH (type) > n)
invalid_synthetic_pointer (); invalid_synthetic_pointer ();
@ -2479,7 +2477,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
retval = allocate_value (type); retval = allocate_value (type);
contents = value_contents_raw (retval); contents = value_contents_raw (retval);
ldata = ctx->data + byte_offset; ldata = ctx.data + byte_offset;
n -= byte_offset; n -= byte_offset;
if (n > TYPE_LENGTH (type)) if (n > TYPE_LENGTH (type))
@ -2509,9 +2507,9 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
} }
} }
set_value_initialized (retval, ctx->initialized); set_value_initialized (retval, ctx.initialized);
do_cleanups (old_chain); do_cleanups (value_chain);
return retval; return retval;
} }
@ -2539,7 +2537,6 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
CORE_ADDR addr, CORE_ADDR addr,
CORE_ADDR *valp) CORE_ADDR *valp)
{ {
struct dwarf_expr_context *ctx;
struct dwarf_expr_baton baton; struct dwarf_expr_baton baton;
struct objfile *objfile; struct objfile *objfile;
struct cleanup *cleanup; struct cleanup *cleanup;
@ -2547,8 +2544,7 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
if (dlbaton == NULL || dlbaton->size == 0) if (dlbaton == NULL || dlbaton->size == 0)
return 0; return 0;
ctx = new_dwarf_expr_context (); dwarf_expr_context ctx;
cleanup = make_cleanup_free_dwarf_expr_context (ctx);
baton.frame = frame; baton.frame = frame;
baton.per_cu = dlbaton->per_cu; baton.per_cu = dlbaton->per_cu;
@ -2556,29 +2552,27 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
objfile = dwarf2_per_cu_objfile (dlbaton->per_cu); objfile = dwarf2_per_cu_objfile (dlbaton->per_cu);
ctx->gdbarch = get_objfile_arch (objfile); ctx.gdbarch = get_objfile_arch (objfile);
ctx->addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu); ctx.addr_size = dwarf2_per_cu_addr_size (dlbaton->per_cu);
ctx->ref_addr_size = dwarf2_per_cu_ref_addr_size (dlbaton->per_cu); ctx.ref_addr_size = dwarf2_per_cu_ref_addr_size (dlbaton->per_cu);
ctx->offset = dwarf2_per_cu_text_offset (dlbaton->per_cu); ctx.offset = dwarf2_per_cu_text_offset (dlbaton->per_cu);
ctx->funcs = &dwarf_expr_ctx_funcs; ctx.funcs = &dwarf_expr_ctx_funcs;
ctx->baton = &baton; ctx.baton = &baton;
dwarf_expr_eval (ctx, dlbaton->data, dlbaton->size); dwarf_expr_eval (&ctx, dlbaton->data, dlbaton->size);
switch (ctx->location) switch (ctx.location)
{ {
case DWARF_VALUE_REGISTER: case DWARF_VALUE_REGISTER:
case DWARF_VALUE_MEMORY: case DWARF_VALUE_MEMORY:
case DWARF_VALUE_STACK: case DWARF_VALUE_STACK:
*valp = dwarf_expr_fetch_address (ctx, 0); *valp = dwarf_expr_fetch_address (&ctx, 0);
if (ctx->location == DWARF_VALUE_REGISTER) if (ctx.location == DWARF_VALUE_REGISTER)
*valp = dwarf_expr_read_addr_from_reg (&baton, *valp); *valp = dwarf_expr_read_addr_from_reg (&baton, *valp);
do_cleanups (cleanup);
return 1; return 1;
case DWARF_VALUE_LITERAL: case DWARF_VALUE_LITERAL:
*valp = extract_signed_integer (ctx->data, ctx->len, *valp = extract_signed_integer (ctx.data, ctx.len,
gdbarch_byte_order (ctx->gdbarch)); gdbarch_byte_order (ctx.gdbarch));
do_cleanups (cleanup);
return 1; return 1;
/* Unsupported dwarf values. */ /* Unsupported dwarf values. */
case DWARF_VALUE_OPTIMIZED_OUT: case DWARF_VALUE_OPTIMIZED_OUT:
@ -2586,7 +2580,6 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
break; break;
} }
do_cleanups (cleanup);
return 0; return 0;
} }
@ -2864,7 +2857,6 @@ 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)
{ {
struct symbol_needs_baton baton; struct symbol_needs_baton baton;
struct dwarf_expr_context *ctx;
int in_reg; int in_reg;
struct cleanup *old_chain; struct cleanup *old_chain;
struct objfile *objfile = dwarf2_per_cu_objfile (per_cu); struct objfile *objfile = dwarf2_per_cu_objfile (per_cu);
@ -2872,29 +2864,28 @@ dwarf2_loc_desc_get_symbol_read_needs (const gdb_byte *data, size_t size,
baton.needs = SYMBOL_NEEDS_NONE; baton.needs = SYMBOL_NEEDS_NONE;
baton.per_cu = per_cu; baton.per_cu = per_cu;
ctx = new_dwarf_expr_context (); dwarf_expr_context ctx;
old_chain = make_cleanup_free_dwarf_expr_context (ctx); old_chain = make_cleanup_value_free_to_mark (value_mark ());
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);
ctx->offset = dwarf2_per_cu_text_offset (per_cu); ctx.offset = dwarf2_per_cu_text_offset (per_cu);
ctx->baton = &baton; ctx.baton = &baton;
ctx->funcs = &symbol_needs_ctx_funcs; ctx.funcs = &symbol_needs_ctx_funcs;
dwarf_expr_eval (ctx, data, size); dwarf_expr_eval (&ctx, data, size);
in_reg = ctx->location == DWARF_VALUE_REGISTER; in_reg = ctx.location == DWARF_VALUE_REGISTER;
if (ctx->num_pieces > 0) if (ctx.num_pieces > 0)
{ {
int i; int i;
/* If the location has several pieces, and any of them are in /* If the location has several pieces, and any of them are in
registers, then we will need a frame to fetch them from. */ registers, then we will need a frame to fetch them from. */
for (i = 0; i < ctx->num_pieces; i++) for (i = 0; i < ctx.num_pieces; i++)
if (ctx->pieces[i].location == DWARF_VALUE_REGISTER) if (ctx.pieces[i].location == DWARF_VALUE_REGISTER)
in_reg = 1; in_reg = 1;
} }