+2008-11-26 Jerome Guitton <guitton@adacore.com>
+
+ * value.h (allocate_value_lazy): New function declaration.
+ (value_free): Remove macro, make it a function.
+ * value.c (value): Move actual content outside of the memory space
+ of the struct; add a pointer to this actual content.
+ (allocate_value_lazy, allocate_value_contents): New function.
+ (allocate_value): Reimplement using these two new functions.
+ (value_contents_raw, value_contents_all_raw): If no memory
+ has been allocated yet for the actual content, allocate it.
+ (value_contents_all): Resync with struct value's changes.
+ (value_free): New function.
+ (value_copy, value_primitive_field): Use new function
+ allocate_value_lazy to allocate lazy values.
+ (value_change_enclosing_type): Resync with struct value's changes.
+ As the value is not reallocated, remove the special handling for
+ the value chain (now obsolete).
+ * valops.c (value_at_lazy): Use new function allocate_value_lazy.
+ (value_fetch_lazy): Allocate value content. Use allocate_value_lazy
+ to allocate lazy values.
+ (value_slice): Use allocate_value_lazy to allocate lazy values.
+
2008-11-25 Jan Kratochvil <jan.kratochvil@redhat.com>
Fix automatic restoration of breakpoints memory for ia64.
if (TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID)
error (_("Attempt to dereference a generic pointer."));
- val = allocate_value (type);
+ val = allocate_value_lazy (type);
VALUE_LVAL (val) = lval_memory;
VALUE_ADDRESS (val) = addr;
- set_value_lazy (val, 1);
return val;
}
int
value_fetch_lazy (struct value *val)
{
+ gdb_assert (value_lazy (val));
+ allocate_value_contents (val);
if (VALUE_LVAL (val) == lval_memory)
{
CORE_ADDR addr = VALUE_ADDRESS (val) + value_offset (val);
if (BASETYPE_VIA_VIRTUAL (type, i))
{
int boffset;
- struct value *v2 = allocate_value (basetype);
+ struct value *v2;
boffset = baseclass_offset (type, i,
value_contents (arg1) + offset,
{
CORE_ADDR base_addr;
+ v2 = allocate_value (basetype);
base_addr =
VALUE_ADDRESS (arg1) + value_offset (arg1) + boffset;
if (target_read_memory (base_addr,
}
else
{
+ if (VALUE_LVAL (arg1) == lval_memory && value_lazy (arg1))
+ v2 = allocate_value_lazy (basetype);
+ else
+ {
+ v2 = allocate_value (basetype);
+ memcpy (value_contents_raw (v2),
+ value_contents_raw (arg1) + boffset,
+ TYPE_LENGTH (basetype));
+ }
VALUE_LVAL (v2) = VALUE_LVAL (arg1);
VALUE_ADDRESS (v2) = VALUE_ADDRESS (arg1);
VALUE_FRAME_ID (v2) = VALUE_FRAME_ID (arg1);
set_value_offset (v2, value_offset (arg1) + boffset);
- if (VALUE_LVAL (arg1) == lval_memory && value_lazy (arg1))
- set_value_lazy (v2, 1);
- else
- memcpy (value_contents_raw (v2),
- value_contents_raw (arg1) + boffset,
- TYPE_LENGTH (basetype));
}
if (found_baseclass)
slice_range_type);
TYPE_CODE (slice_type) = TYPE_CODE (array_type);
- slice = allocate_value (slice_type);
if (VALUE_LVAL (array) == lval_memory && value_lazy (array))
- set_value_lazy (slice, 1);
+ slice = allocate_value_lazy (slice_type);
else
- memcpy (value_contents_writeable (slice),
- value_contents (array) + offset,
- TYPE_LENGTH (slice_type));
+ {
+ slice = allocate_value (slice_type);
+ memcpy (value_contents_writeable (slice),
+ value_contents (array) + offset,
+ TYPE_LENGTH (slice_type));
+ }
if (VALUE_LVAL (array) == lval_internalvar)
VALUE_LVAL (slice) = lval_internalvar_component;
/* If value is a variable, is it initialized or not. */
int initialized;
- /* Actual contents of the value. For use of this value; setting it
- uses the stuff above. Not valid if lazy is nonzero. Target
- byte-order. We force it to be aligned properly for any possible
- value. Note that a value therefore extends beyond what is
- declared here. */
- union
- {
- gdb_byte contents[1];
- DOUBLEST force_doublest_align;
- LONGEST force_longest_align;
- CORE_ADDR force_core_addr_align;
- void *force_pointer_align;
- } aligner;
- /* Do not add any new members here -- contents above will trash
- them. */
+ /* Actual contents of the value. Target byte-order. NULL or not
+ valid if lazy is nonzero. */
+ gdb_byte *contents;
};
/* Prototypes for local functions. */
static struct value *all_values;
-/* Allocate a value that has the correct length for type TYPE. */
+/* Allocate a lazy value for type TYPE. Its actual content is
+ "lazily" allocated too: the content field of the return value is
+ NULL; it will be allocated when it is fetched from the target. */
struct value *
-allocate_value (struct type *type)
+allocate_value_lazy (struct type *type)
{
struct value *val;
struct type *atype = check_typedef (type);
- val = (struct value *) xzalloc (sizeof (struct value) + TYPE_LENGTH (atype));
+ val = (struct value *) xzalloc (sizeof (struct value));
+ val->contents = NULL;
val->next = all_values;
all_values = val;
val->type = type;
val->bitpos = 0;
val->bitsize = 0;
VALUE_REGNUM (val) = -1;
- val->lazy = 0;
+ val->lazy = 1;
val->optimized_out = 0;
val->embedded_offset = 0;
val->pointed_to_offset = 0;
return val;
}
+/* Allocate the contents of VAL if it has not been allocated yet. */
+
+void
+allocate_value_contents (struct value *val)
+{
+ if (!val->contents)
+ val->contents = (gdb_byte *) xzalloc (TYPE_LENGTH (val->enclosing_type));
+}
+
+/* Allocate a value and its contents for type TYPE. */
+
+struct value *
+allocate_value (struct type *type)
+{
+ struct value *val = allocate_value_lazy (type);
+ allocate_value_contents (val);
+ val->lazy = 0;
+ return val;
+}
+
/* Allocate a value that has the correct length
for COUNT repetitions of type TYPE. */
gdb_byte *
value_contents_raw (struct value *value)
{
- return value->aligner.contents + value->embedded_offset;
+ allocate_value_contents (value);
+ return value->contents + value->embedded_offset;
}
gdb_byte *
value_contents_all_raw (struct value *value)
{
- return value->aligner.contents;
+ allocate_value_contents (value);
+ return value->contents;
}
struct type *
{
if (value->lazy)
value_fetch_lazy (value);
- return value->aligner.contents;
+ return value->contents;
}
int
return all_values;
}
+void
+value_free (struct value *val)
+{
+ if (val)
+ xfree (val->contents);
+ xfree (val);
+}
+
/* Free all values allocated since MARK was obtained by value_mark
(except for those released). */
void
value_copy (struct value *arg)
{
struct type *encl_type = value_enclosing_type (arg);
- struct value *val = allocate_value (encl_type);
+ struct value *val;
+
+ if (value_lazy (arg))
+ val = allocate_value_lazy (encl_type);
+ else
+ val = allocate_value (encl_type);
val->type = arg->type;
VALUE_LVAL (val) = VALUE_LVAL (arg);
val->location = arg->location;
struct value *
value_change_enclosing_type (struct value *val, struct type *new_encl_type)
{
- if (TYPE_LENGTH (new_encl_type) <= TYPE_LENGTH (value_enclosing_type (val)))
- {
- val->enclosing_type = new_encl_type;
- return val;
- }
- else
- {
- struct value *new_val;
- struct value *prev;
-
- new_val = (struct value *) xrealloc (val, sizeof (struct value) + TYPE_LENGTH (new_encl_type));
-
- new_val->enclosing_type = new_encl_type;
-
- /* We have to make sure this ends up in the same place in the value
- chain as the original copy, so it's clean-up behavior is the same.
- If the value has been released, this is a waste of time, but there
- is no way to tell that in advance, so... */
-
- if (val != all_values)
- {
- for (prev = all_values; prev != NULL; prev = prev->next)
- {
- if (prev->next == val)
- {
- prev->next = new_val;
- break;
- }
- }
- }
-
- return new_val;
- }
+ if (TYPE_LENGTH (new_encl_type) > TYPE_LENGTH (value_enclosing_type (val)))
+ val->contents =
+ (gdb_byte *) xrealloc (val->contents, TYPE_LENGTH (new_encl_type));
+
+ val->enclosing_type = new_encl_type;
+ return val;
}
/* Given a value ARG1 (offset by OFFSET bytes)
/* This field is actually a base subobject, so preserve the
entire object's contents for later references to virtual
bases, etc. */
- v = allocate_value (value_enclosing_type (arg1));
- v->type = type;
/* Lazy register values with offsets are not supported. */
if (VALUE_LVAL (arg1) == lval_register && value_lazy (arg1))
value_fetch_lazy (arg1);
if (value_lazy (arg1))
- set_value_lazy (v, 1);
+ v = allocate_value_lazy (value_enclosing_type (arg1));
else
- memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1),
- TYPE_LENGTH (value_enclosing_type (arg1)));
+ {
+ v = allocate_value (value_enclosing_type (arg1));
+ memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1),
+ TYPE_LENGTH (value_enclosing_type (arg1)));
+ }
+ v->type = type;
v->offset = value_offset (arg1);
v->embedded_offset = (offset + value_embedded_offset (arg1)
+ TYPE_FIELD_BITPOS (arg_type, fieldno) / 8);
{
/* Plain old data member */
offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
- v = allocate_value (type);
/* Lazy register values with offsets are not supported. */
if (VALUE_LVAL (arg1) == lval_register && value_lazy (arg1))
value_fetch_lazy (arg1);
if (value_lazy (arg1))
- set_value_lazy (v, 1);
+ v = allocate_value_lazy (type);
else
- memcpy (value_contents_raw (v),
- value_contents_raw (arg1) + offset,
- TYPE_LENGTH (type));
+ {
+ v = allocate_value (type);
+ memcpy (value_contents_raw (v),
+ value_contents_raw (arg1) + offset,
+ TYPE_LENGTH (type));
+ }
v->offset = (value_offset (arg1) + offset
+ value_embedded_offset (arg1));
}