Lazy bitfields
Daniel Jacobowitz
drow@false.org
Thu Feb 8 15:59:00 GMT 2007
On Wed, Jan 24, 2007 at 11:23:43AM +0300, Vladimir Prus wrote:
> One nit is that when writing a bitfield, we first fetch the entire
> parent value, modify bits and write entire parent value. In some
> *limited* set of cases it is possible to read only some of the bytes,
> or not read anything at all, but introducing bit-mask telling which
> bits are read and which are not is more trouble that its worth.
The other nit is that when we read a bitfield, we read the whole
struct, which might be much larger.
I don't think either of these nits are problematic. Your approach
seems fine.
> +extern struct value *value_parent (struct value *value)
> +{
> + return value->parent;
> +}
> +
> +extern int value_fieldno (struct value *value)
> +{
> + return value->fieldno;
> +}
> +extern void value_free (struct value *value)
I haven't gotten to complain about your formatting in a while :-)
Function at start of line please.
> + /* If there's a parent, drop parents's reference count
"parent's"
> @@ -562,6 +601,11 @@ value_copy (struct value *arg)
> val->embedded_offset = value_embedded_offset (arg);
> val->pointed_to_offset = arg->pointed_to_offset;
> val->modifiable = arg->modifiable;
> + val->fieldno = arg->fieldno;
> + val->parent = arg->parent;
> + if (val->parent)
> + ++val->parent->reference_count;
> + val->reference_count = 1;
Don't think you need the last line - allocate_value should have set
it to one.
> @@ -1300,15 +1344,23 @@ value_primitive_field (struct value *arg
>
> if (TYPE_FIELD_BITSIZE (arg_type, fieldno))
> {
> - v = value_from_longest (type,
> - unpack_field_as_long (arg_type,
> - value_contents (arg1)
> - + offset,
> - fieldno));
> + LONGEST num;
> + int len;
> +
> +
> + v = allocate_value (type);
> v->bitpos = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8;
> v->bitsize = TYPE_FIELD_BITSIZE (arg_type, fieldno);
> v->offset = value_offset (arg1) + offset
> + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
> + v->parent = arg1;
> + v->lval = lval_bitfield;
> + v->fieldno = fieldno;
> +
> + if (!value_lazy (arg1))
> + value_fetch_lazy (v);
> + else
> + set_value_lazy (v, 1);
> }
> else if (fieldno < TYPE_N_BASECLASSES (arg_type))
> {
Two problems here. First of all, the whole point of adding reference
counts is to increment the parent's reference count here, right?
Better do that then :-)
Second, I'm worried about the "offset" argument to
value_primitive_field. This was primarily for CHILL, due to a
strange choice when generating or reading debug info, and it's
possible that it's never non-zero any more, which would be nice.
But if it ever is non-zero, this will break it. It gets lumped
in with value_offset so when you call unpack_field_as_long in
value_fetch_lazy you can't pick it out again to apply it to the
parent.
That's my only real concern with this patch; everything else
looks OK. I'm going to try to figure out if that argument is
ever non-zero or if we can eliminate it now.
--
Daniel Jacobowitz
CodeSourcery
More information about the Gdb-patches
mailing list