* value.h (value_available_contents_eq): Declare.
	* value.c (find_first_range_overlap): New function.
	(value_available_contents_eq): New function.
	* valprint.c (val_print_array_elements): Use
	value_available_contents_eq.
	* ada-valprint.c (val_print_packed_array_elements): Use
	value_available_contents_eq.
	* jv-valprint.c (java_value_print): Use
	value_available_contents_eq.
This commit is contained in:
Pedro Alves 2011-02-14 11:23:33 +00:00
parent e6e4e7014d
commit c8c1c22fea
6 changed files with 151 additions and 6 deletions

View file

@ -1,3 +1,15 @@
2011-02-14 Pedro Alves <pedro@codesourcery.com>
* value.h (value_available_contents_eq): Declare.
* value.c (find_first_range_overlap): New function.
(value_available_contents_eq): New function.
* valprint.c (val_print_array_elements): Use
value_available_contents_eq.
* ada-valprint.c (val_print_packed_array_elements): Use
value_available_contents_eq.
* jv-valprint.c (java_value_print): Use
value_available_contents_eq.
2011-02-14 Pedro Alves <pedro@codesourcery.com>
* target.c (target_read_live_memory): New function.

View file

@ -200,7 +200,9 @@ val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr,
(i * bitsize) / HOST_CHAR_BIT,
(i * bitsize) % HOST_CHAR_BIT,
bitsize, elttype);
if (memcmp (value_contents (v0), value_contents (v1), eltlen) != 0)
if (!value_available_contents_eq (v0, value_embedded_offset (v0),
v1, value_embedded_offset (v1),
eltlen))
break;
}

View file

@ -179,8 +179,11 @@ java_value_print (struct value *val, struct ui_file *stream,
set_value_lazy (next_v, 1);
set_value_offset (next_v, value_offset (next_v)
+ TYPE_LENGTH (el_type));
if (memcmp (value_contents (v), value_contents (next_v),
TYPE_LENGTH (el_type)) != 0)
value_fetch_lazy (next_v);
if (!(value_available_contents_eq
(v, value_embedded_offset (v),
next_v, value_embedded_offset (next_v),
TYPE_LENGTH (el_type))))
break;
}

View file

@ -1242,9 +1242,11 @@ val_print_array_elements (struct type *type,
rep1 = i + 1;
reps = 1;
while (rep1 < len
&& memcmp (valaddr + embedded_offset + i * eltlen,
valaddr + embedded_offset + rep1 * eltlen,
eltlen) == 0)
&& value_available_contents_eq (val,
embedded_offset + i * eltlen,
val,
embedded_offset + rep1 * eltlen,
eltlen))
{
++reps;
++rep1;

View file

@ -496,6 +496,107 @@ mark_value_bytes_unavailable (struct value *value, int offset, int length)
}
}
/* Find the first range in RANGES that overlaps the range defined by
OFFSET and LENGTH, starting at element POS in the RANGES vector,
Returns the index into RANGES where such overlapping range was
found, or -1 if none was found. */
static int
find_first_range_overlap (VEC(range_s) *ranges, int pos,
int offset, int length)
{
range_s *r;
int i;
for (i = pos; VEC_iterate (range_s, ranges, i, r); i++)
if (ranges_overlap (r->offset, r->length, offset, length))
return i;
return -1;
}
int
value_available_contents_eq (const struct value *val1, int offset1,
const struct value *val2, int offset2,
int length)
{
int org_len = length;
int org_offset1 = offset1;
int org_offset2 = offset2;
int idx1 = 0, idx2 = 0;
int prev_avail;
/* This routine is used by printing routines, where we should
already have read the value. Note that we only know whether a
value chunk is available if we've tried to read it. */
gdb_assert (!val1->lazy && !val2->lazy);
/* The offset from either ORG_OFFSET1 or ORG_OFFSET2 where the
available contents we haven't compared yet start. */
prev_avail = 0;
while (length > 0)
{
range_s *r1, *r2;
ULONGEST l1, h1;
ULONGEST l2, h2;
idx1 = find_first_range_overlap (val1->unavailable, idx1,
offset1, length);
idx2 = find_first_range_overlap (val2->unavailable, idx2,
offset2, length);
/* The usual case is for both values to be completely available. */
if (idx1 == -1 && idx2 == -1)
return (memcmp (val1->contents + org_offset1 + prev_avail,
val2->contents + org_offset2 + prev_avail,
org_len - prev_avail) == 0);
/* The contents only match equal if the available set matches as
well. */
else if (idx1 == -1 || idx2 == -1)
return 0;
gdb_assert (idx1 != -1 && idx2 != -1);
r1 = VEC_index (range_s, val1->unavailable, idx1);
r2 = VEC_index (range_s, val2->unavailable, idx2);
/* Get the unavailable windows intersected by the incoming
ranges. The first and last ranges that overlap the argument
range may be wider than said incoming arguments ranges. */
l1 = max (offset1, r1->offset);
h1 = min (offset1 + length, r1->offset + r1->length);
l2 = max (offset2, r2->offset);
h2 = min (offset2 + length, r2->offset + r2->length);
/* Make them relative to the respective start offsets, so we can
compare them for equality. */
l1 -= offset1;
h1 -= offset1;
l2 -= offset2;
h2 -= offset2;
/* Different availability, no match. */
if (l1 != l2 || h1 != h2)
return 0;
/* Compare the _available_ contents. */
if (memcmp (val1->contents + org_offset1 + prev_avail,
val2->contents + org_offset2 + prev_avail,
l2 - prev_avail) != 0)
return 0;
prev_avail += h1;
length -= h1;
offset1 += h1;
offset2 += h1;
}
return 1;
}
/* Prototypes for local functions. */
static void show_values (char *, int);

View file

@ -374,6 +374,31 @@ extern int value_bytes_available (const struct value *value,
extern void mark_value_bytes_unavailable (struct value *value,
int offset, int length);
/* Compare LENGTH bytes of VAL1's contents starting at OFFSET1 with
LENGTH bytes of VAL2's contents starting at OFFSET2. Returns true
iff the set of available contents match. Unavailable contents
compare equal with unavailable contents, and different with any
available byte. For example, if 'x's represent an unavailable
byte, and 'V' and 'Z' represent different available bytes, in a
value with length 16:
offset: 0 4 8 12 16
contents: xxxxVVVVxxxxVVZZ
then:
value_available_contents_eq(val, 0, val, 8, 6) => 1
value_available_contents_eq(val, 0, val, 4, 4) => 1
value_available_contents_eq(val, 0, val, 8, 8) => 0
value_available_contents_eq(val, 4, val, 12, 2) => 1
value_available_contents_eq(val, 4, val, 12, 4) => 0
value_available_contents_eq(val, 3, val, 4, 4) => 0
*/
extern int value_available_contents_eq (const struct value *val1, int offset1,
const struct value *val2, int offset2,
int length);
/* Read LENGTH bytes of memory starting at MEMADDR into BUFFER, which
is (or will be copied to) VAL's contents buffer offset by
EMBEDDED_OFFSET (that is, to &VAL->contents[EMBEDDED_OFFSET]).