gdb/
authorPedro Alves <palves@redhat.com>
Mon, 14 Feb 2011 11:23:33 +0000 (11:23 +0000)
committerPedro Alves <palves@redhat.com>
Mon, 14 Feb 2011 11:23:33 +0000 (11:23 +0000)
* 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.

gdb/ChangeLog
gdb/ada-valprint.c
gdb/jv-valprint.c
gdb/valprint.c
gdb/value.c
gdb/value.h

index 4440c09a13853917814438292906633bd5cdd39f..92a6d4eb574739def21e3f251ed3f9862e55e553 100644 (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.
index bc3ea2678b4cdcbc030e852d3001bd664af270fc..9381ecca5cdcc5945296bd844ada172610fb5127 100644 (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;
        }
 
index 0e5b97f10ccda85a67179a85cf1757caa3675d12..bed9b2f396c1c4edd271de399efc27b163c778c6 100644 (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;
                }
 
index 64a4b05f52744e7cf64f038fadf30606a59c5227..fd573c255e7ce72de66b743ff1f31a189bdbe0d3 100644 (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;
index 58190ea49a641940a344c4b6c38b456351d9391a..a8be549d9c2ff9c674e0e9581cdc79c8350cdd54 100644 (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);
index d2eb091ef5c364c05585bc22ecfd48310aa2ab38..0feb92fc88a6fa2ed7162b650d43729664268a1b 100644 (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]).