From 3e3d7139eef55bf54263b7385858bcdd2b239415 Mon Sep 17 00:00:00 2001 From: Jerome Guitton Date: Wed, 26 Nov 2008 16:27:28 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 22 ++++++++ gdb/valops.c | 35 +++++++------ gdb/value.c | 135 ++++++++++++++++++++++++++------------------------ gdb/value.h | 4 +- 4 files changed, 115 insertions(+), 81 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0582ae11195..45cf07c62c4 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,25 @@ +2008-11-26 Jerome Guitton + + * 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 Fix automatic restoration of breakpoints memory for ia64. diff --git a/gdb/valops.c b/gdb/valops.c index 0c539c159b0..05e53513c66 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -608,11 +608,10 @@ value_at_lazy (struct type *type, CORE_ADDR addr) 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; } @@ -634,6 +633,8 @@ value_at_lazy (struct type *type, CORE_ADDR addr) 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); @@ -1535,7 +1536,7 @@ search_struct_field (char *name, struct value *arg1, int offset, 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, @@ -1553,6 +1554,7 @@ search_struct_field (char *name, struct value *arg1, int offset, { CORE_ADDR base_addr; + v2 = allocate_value (basetype); base_addr = VALUE_ADDRESS (arg1) + value_offset (arg1) + boffset; if (target_read_memory (base_addr, @@ -1564,16 +1566,19 @@ search_struct_field (char *name, struct value *arg1, int offset, } 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) @@ -2969,13 +2974,15 @@ value_slice (struct value *array, int lowbound, int length) 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; diff --git a/gdb/value.c b/gdb/value.c index 904b942ac34..203e86b935c 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -163,21 +163,9 @@ struct value /* 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. */ @@ -213,15 +201,18 @@ static int value_history_count; /* Abs number of last entry stored */ 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; @@ -233,7 +224,7 @@ allocate_value (struct 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; @@ -242,6 +233,26 @@ allocate_value (struct type *type) 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. */ @@ -340,13 +351,15 @@ set_value_bitsize (struct value *value, int bit) 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 * @@ -360,7 +373,7 @@ value_contents_all (struct value *value) { if (value->lazy) value_fetch_lazy (value); - return value->aligner.contents; + return value->contents; } int @@ -495,6 +508,14 @@ value_mark (void) 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 @@ -579,7 +600,12 @@ struct value * 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; @@ -1319,39 +1345,12 @@ value_static_field (struct type *type, int fieldno) 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) @@ -1388,18 +1387,20 @@ value_primitive_field (struct value *arg1, int offset, /* 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); @@ -1408,18 +1409,20 @@ value_primitive_field (struct value *arg1, int offset, { /* 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)); } diff --git a/gdb/value.h b/gdb/value.h index 384a1ed391e..a882004e5ce 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -318,6 +318,8 @@ extern struct value *locate_var_value (struct symbol *var, struct frame_info *frame); extern struct value *allocate_value (struct type *type); +extern struct value *allocate_value_lazy (struct type *type); +extern void allocate_value_contents (struct value *value); extern struct value *allocate_repeat_value (struct type *type, int count); @@ -504,7 +506,7 @@ extern int unop_user_defined_p (enum exp_opcode op, struct value *arg1); extern int destructor_name_p (const char *name, const struct type *type); -#define value_free(val) xfree (val) +extern void value_free (struct value *val); extern void free_all_values (void); -- 2.30.2