This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch 1/2] Make values more lazy if possible
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gdb-patches at sourceware dot org
- Cc: Andrew Burgess <aburgess at broadcom dot com>
- Date: Thu, 6 Jan 2011 13:03:12 +0100
- Subject: [patch 1/2] Make values more lazy if possible
Hi,
currently sometimes value->contents is allocated despite value->lazy is set.
Together with [patch 2/2] of this series it can have a memory allocation
regression as without this patch GDB would start to needlessly malloc huge
amounts of memory for `print verybigarray(1,1)' (if the N-1 dimensions
subarray is still big).
It is not completely safe as for example was found the unhandled case in
value_fetch_lazy, hopefully the testsuite caught it all.
No regressions on {x86_64,x86_64-m32,i686}-fedora14-linux-gnu.
Thanks,
Jan
gdb/
2011-01-06 Jan Kratochvil <jan.kratochvil@redhat.com>
Make value allocations more lazy.
* ada-lang.c (coerce_unspec_val_to_type): Use allocate_value_lazy
instead of allocate_value and set_value_lazy when possible.
* dwarf2loc.c (dwarf2_evaluate_loc_desc_full): Use allocate_value_lazy
instead of allocate_value and set_value_lazy.
* findvar.c (value_of_register_lazy): Likewise.
(read_var_value): Remove V preallocation, call just check_typedef in
advance. Move allocate_value to LOC_CONST, LOC_LABEL,
LOC_CONST_BYTES. Use allocate_value_lazy in LOC_STATIC, LOC_ARG,
LOC_REF_ARG, LOC_LOCAL, LOC_BLOCK. Set ADDR instead of
set_value_address and break in LOC_BLOCK. Use allocate_value_lazy and
remove lval_memory set in LOC_REGPARM_ADDR. Use allocate_value_lazy
in LOC_UNRESOLVED and LOC_OPTIMIZED_OUT. Add setting lval_memory at
the end, remove set_value_lazy there.
* valarith.c (value_subscripted_rvalue): Use allocate_value_lazy
instead of allocate_value and set_value_lazy when possible.
* valops.c (value_fetch_lazy): Do nop for value_optimized_out VAL.
* value.c (allocate_computed_value): Use allocate_value_lazy instead
of allocate_value and set_value_lazy.
(value_from_contents_and_address): Use allocate_value_lazy instead of
allocate_value and set_value_lazy when possible.
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -555,17 +555,19 @@ coerce_unspec_val_to_type (struct value *val, struct type *type)
trying to allocate some memory for it. */
check_size (type);
- result = allocate_value (type);
+ if (value_lazy (val)
+ || TYPE_LENGTH (type) > TYPE_LENGTH (value_type (val)))
+ result = allocate_value_lazy (type);
+ else
+ {
+ result = allocate_value (type);
+ memcpy (value_contents_raw (result), value_contents (val),
+ TYPE_LENGTH (type));
+ }
set_value_component_location (result, val);
set_value_bitsize (result, value_bitsize (val));
set_value_bitpos (result, value_bitpos (val));
set_value_address (result, value_address (val));
- if (value_lazy (val)
- || TYPE_LENGTH (type) > TYPE_LENGTH (value_type (val)))
- set_value_lazy (result, 1);
- else
- memcpy (value_contents_raw (result), value_contents (val),
- TYPE_LENGTH (type));
return result;
}
}
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1123,9 +1123,8 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
CORE_ADDR address = dwarf_expr_fetch_address (ctx, 0);
int in_stack_memory = dwarf_expr_fetch_in_stack_memory (ctx, 0);
- retval = allocate_value (type);
+ retval = allocate_value_lazy (type);
VALUE_LVAL (retval) = lval_memory;
- set_value_lazy (retval, 1);
if (in_stack_memory)
set_value_stack (retval, 1);
set_value_address (retval, address + byte_offset);
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -306,11 +306,10 @@ value_of_register_lazy (struct frame_info *frame, int regnum)
/* We should have a valid (i.e. non-sentinel) frame. */
gdb_assert (frame_id_p (get_frame_id (frame)));
- reg_val = allocate_value (register_type (gdbarch, regnum));
+ reg_val = allocate_value_lazy (register_type (gdbarch, regnum));
VALUE_LVAL (reg_val) = lval_register;
VALUE_REGNUM (reg_val) = regnum;
VALUE_FRAME_ID (reg_val) = get_frame_id (frame);
- set_value_lazy (reg_val, 1);
return reg_val;
}
@@ -411,15 +410,12 @@ read_var_value (struct symbol *var, struct frame_info *frame)
CORE_ADDR addr;
int len;
- if (SYMBOL_CLASS (var) == LOC_COMPUTED
- || SYMBOL_CLASS (var) == LOC_REGISTER)
- /* These cases do not use V. */
- v = NULL;
- else
- {
- v = allocate_value (type);
- VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */
- }
+ /* Call check_typedef on our type to make sure that, if TYPE is
+ a TYPE_CODE_TYPEDEF, its length is set to the length of the target type
+ instead of zero. However, we do not replace the typedef type by the
+ target type, because we want to keep the typedef in order to be able to
+ set the returned value type description correctly. */
+ check_typedef (type);
len = TYPE_LENGTH (type);
@@ -430,6 +426,7 @@ read_var_value (struct symbol *var, struct frame_info *frame)
{
case LOC_CONST:
/* Put the constant back in target format. */
+ v = allocate_value (type);
store_signed_integer (value_contents_raw (v), len,
gdbarch_byte_order (get_type_arch (type)),
(LONGEST) SYMBOL_VALUE (var));
@@ -438,6 +435,7 @@ read_var_value (struct symbol *var, struct frame_info *frame)
case LOC_LABEL:
/* Put the constant back in target format. */
+ v = allocate_value (type);
if (overlay_debugging)
{
CORE_ADDR addr
@@ -453,11 +451,13 @@ read_var_value (struct symbol *var, struct frame_info *frame)
return v;
case LOC_CONST_BYTES:
+ v = allocate_value (type);
memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var), len);
VALUE_LVAL (v) = not_lval;
return v;
case LOC_STATIC:
+ v = allocate_value_lazy (type);
if (overlay_debugging)
addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
SYMBOL_OBJ_SECTION (var));
@@ -470,6 +470,7 @@ read_var_value (struct symbol *var, struct frame_info *frame)
if (!addr)
return 0;
addr += SYMBOL_VALUE (var);
+ v = allocate_value_lazy (type);
break;
case LOC_REF_ARG:
@@ -483,12 +484,14 @@ read_var_value (struct symbol *var, struct frame_info *frame)
argref += SYMBOL_VALUE (var);
ref = value_at (lookup_pointer_type (type), argref);
addr = value_as_address (ref);
+ v = allocate_value_lazy (type);
break;
}
case LOC_LOCAL:
addr = get_frame_locals_address (frame);
addr += SYMBOL_VALUE (var);
+ v = allocate_value_lazy (type);
break;
case LOC_TYPEDEF:
@@ -496,12 +499,13 @@ read_var_value (struct symbol *var, struct frame_info *frame)
break;
case LOC_BLOCK:
+ v = allocate_value_lazy (type);
if (overlay_debugging)
- set_value_address (v, symbol_overlayed_address
- (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_OBJ_SECTION (var)));
+ addr = symbol_overlayed_address
+ (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_OBJ_SECTION (var));
else
- set_value_address (v, BLOCK_START (SYMBOL_BLOCK_VALUE (var)));
- return v;
+ addr = BLOCK_START (SYMBOL_BLOCK_VALUE (var));
+ break;
case LOC_REGISTER:
case LOC_REGPARM_ADDR:
@@ -520,7 +524,7 @@ read_var_value (struct symbol *var, struct frame_info *frame)
error (_("Value of register variable not available."));
addr = value_as_address (regval);
- VALUE_LVAL (v) = lval_memory;
+ v = allocate_value_lazy (type);
}
else
{
@@ -559,10 +563,12 @@ read_var_value (struct symbol *var, struct frame_info *frame)
if (obj_section
&& (obj_section->the_bfd_section->flags & SEC_THREAD_LOCAL) != 0)
addr = target_translate_tls_address (obj_section->objfile, addr);
+ v = allocate_value_lazy (type);
}
break;
case LOC_OPTIMIZED_OUT:
+ v = allocate_value_lazy (type);
VALUE_LVAL (v) = not_lval;
set_value_optimized_out (v, 1);
return v;
@@ -572,8 +578,8 @@ read_var_value (struct symbol *var, struct frame_info *frame)
break;
}
+ VALUE_LVAL (v) = lval_memory;
set_value_address (v, addr);
- set_value_lazy (v, 1);
return v;
}
--- a/gdb/valarith.c
+++ b/gdb/valarith.c
@@ -206,12 +206,14 @@ value_subscripted_rvalue (struct value *array, LONGEST index, int lowerbound)
&& elt_offs >= TYPE_LENGTH (array_type)))
error (_("no such vector element"));
- v = allocate_value (elt_type);
if (VALUE_LVAL (array) == lval_memory && value_lazy (array))
- set_value_lazy (v, 1);
+ v = allocate_value_lazy (elt_type);
else
- memcpy (value_contents_writeable (v),
- value_contents (array) + elt_offs, elt_size);
+ {
+ v = allocate_value (elt_type);
+ memcpy (value_contents_writeable (v),
+ value_contents (array) + elt_offs, elt_size);
+ }
set_value_component_location (v, array);
VALUE_REGNUM (v) = VALUE_REGNUM (array);
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1104,6 +1104,8 @@ value_fetch_lazy (struct value *val)
}
else if (VALUE_LVAL (val) == lval_computed)
value_computed_funcs (val)->read (val);
+ else if (value_optimized_out (val))
+ /* Keep it optimized out. */;
else
internal_error (__FILE__, __LINE__, "Unexpected lazy value type.");
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -332,12 +332,11 @@ allocate_computed_value (struct type *type,
struct lval_funcs *funcs,
void *closure)
{
- struct value *v = allocate_value (type);
+ struct value *v = allocate_value_lazy (type);
VALUE_LVAL (v) = lval_computed;
v->location.computed.funcs = funcs;
v->location.computed.closure = closure;
- set_value_lazy (v, 1);
return v;
}
@@ -2402,12 +2401,15 @@ value_from_contents_and_address (struct type *type,
const gdb_byte *valaddr,
CORE_ADDR address)
{
- struct value *v = allocate_value (type);
+ struct value *v;
if (valaddr == NULL)
- set_value_lazy (v, 1);
+ v = allocate_value_lazy (type);
else
- memcpy (value_contents_raw (v), valaddr, TYPE_LENGTH (type));
+ {
+ v = allocate_value (type);
+ memcpy (value_contents_raw (v), valaddr, TYPE_LENGTH (type));
+ }
set_value_address (v, address);
VALUE_LVAL (v) = lval_memory;
return v;