emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r106411: Fix another crash due to inc


From: Eli Zaretskii
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r106411: Fix another crash due to incorrect hash value of glyph rows, bug #10035.
Date: Fri, 18 Nov 2011 14:21:42 +0200
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 106411
fixes bug(s): http://debbugs.gnu.org/10035
committer: Eli Zaretskii <address@hidden>
branch nick: trunk
timestamp: Fri 2011-11-18 14:21:42 +0200
message:
  Fix another crash due to incorrect hash value of glyph rows, bug #10035.
  
   src/dispnew.c (swap_glyph_pointers): Swap the used[] arrays and the
   hash values of the two rows.
   (copy_row_except_pointers): Preserve the used[] arrays and the
   hash values of the two rows.
   src/xdisp.c (row_hash): New function, body extracted from
   compute_line_metrics.
   (compute_line_metrics): Call row_hash, instead of computing the
   hash code inline.
   src/dispnew.c (verify_row_hash): Call row_hash for computing the
   hash code of a row, instead of duplicating code from xdisp.c.
   src/dispextern.h (row_hash): Add prototype.
modified:
  src/ChangeLog
  src/dispextern.h
  src/dispnew.c
  src/xdisp.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2011-11-18 09:36:59 +0000
+++ b/src/ChangeLog     2011-11-18 12:21:42 +0000
@@ -1,3 +1,20 @@
+2011-11-18  Eli Zaretskii  <address@hidden>
+
+       * dispnew.c (swap_glyph_pointers): Swap the used[] arrays and the
+       hash values of the two rows.
+       (copy_row_except_pointers): Preserve the used[] arrays and the
+       hash values of the two rows.  (Bug#10035)
+
+       * xdisp.c (row_hash): New function, body extracted from
+       compute_line_metrics.
+       (compute_line_metrics): Call row_hash, instead of computing the
+       hash code inline.
+
+       * dispnew.c (verify_row_hash): Call row_hash for computing the
+       hash code of a row, instead of duplicating code from xdisp.c.
+
+       * dispextern.h (row_hash): Add prototype.
+
 2011-11-18  Tassilo Horn  <address@hidden>
 
        * frame.c (delete_frame): Don't delete the terminal when the last

=== modified file 'src/dispextern.h'
--- a/src/dispextern.h  2011-11-08 20:05:27 +0000
+++ b/src/dispextern.h  2011-11-18 12:21:42 +0000
@@ -3126,6 +3126,9 @@
 void w32_init_fringe (struct redisplay_interface *);
 void w32_reset_fringes (void);
 #endif
+
+extern unsigned row_hash (struct glyph_row *);
+
 /* Defined in image.c */
 
 #ifdef HAVE_WINDOW_SYSTEM

=== modified file 'src/dispnew.c'
--- a/src/dispnew.c     2011-11-17 17:40:48 +0000
+++ b/src/dispnew.c     2011-11-18 12:21:42 +0000
@@ -434,18 +434,7 @@
 int
 verify_row_hash (struct glyph_row *row)
 {
-  int area, k;
-  unsigned row_hash = 0;
-
-  for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
-    for (k = 0; k < row->used[area]; ++k)
-      row_hash = ((((row_hash << 4) + (row_hash >> 24)) & 0x0fffffff)
-                 + row->glyphs[area][k].u.val
-                 + row->glyphs[area][k].face_id
-                 + row->glyphs[area][k].padding_p
-                 + (row->glyphs[area][k].type << 2));
-
-  return row_hash == row->hash;
+  return row->hash == row_hash (row);
 }
 #endif
 
@@ -1083,37 +1072,55 @@
 
 #endif /* 0 */
 
-/* Exchange pointers to glyph memory between glyph rows A and B.  */
+/* Exchange pointers to glyph memory between glyph rows A and B.  Also
+   exchange the used[] array and the hash values of the rows, because
+   these should all go together for the row's hash value to be
+   correct.  */
 
 static inline void
 swap_glyph_pointers (struct glyph_row *a, struct glyph_row *b)
 {
   int i;
+  unsigned hash_tem = a->hash;
+
   for (i = 0; i < LAST_AREA + 1; ++i)
     {
       struct glyph *temp = a->glyphs[i];
+      short used_tem = a->used[i];
+
       a->glyphs[i] = b->glyphs[i];
       b->glyphs[i] = temp;
+      a->used[i] = b->used[i];
+      b->used[i] = used_tem;
     }
+  a->hash = b->hash;
+  b->hash = hash_tem;
 }
 
 
 /* Copy glyph row structure FROM to glyph row structure TO, except
-   that glyph pointers in the structures are left unchanged.  */
+   that glyph pointers, the `used' counts, and the hash values in the
+   structures are left unchanged.  */
 
 static inline void
 copy_row_except_pointers (struct glyph_row *to, struct glyph_row *from)
 {
   struct glyph *pointers[1 + LAST_AREA];
+  short used[1 + LAST_AREA];
+  unsigned hashval;
 
   /* Save glyph pointers of TO.  */
   memcpy (pointers, to->glyphs, sizeof to->glyphs);
+  memcpy (used, to->used, sizeof to->used);
+  hashval = to->hash;
 
   /* Do a structure assignment.  */
   *to = *from;
 
   /* Restore original pointers of TO.  */
   memcpy (to->glyphs, pointers, sizeof to->glyphs);
+  memcpy (to->used, used, sizeof to->used);
+  to->hash = hashval;
 }
 
 

=== modified file 'src/xdisp.c'
--- a/src/xdisp.c       2011-11-15 07:55:13 +0000
+++ b/src/xdisp.c       2011-11-18 12:21:42 +0000
@@ -17949,6 +17949,23 @@
     }
 }
 
+/* Compute the hash code for ROW.  */
+unsigned
+row_hash (struct glyph_row *row)
+{
+  int area, k;
+  unsigned hashval = 0;
+
+  for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
+    for (k = 0; k < row->used[area]; ++k)
+      hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
+                 + row->glyphs[area][k].u.val
+                 + row->glyphs[area][k].face_id
+                 + row->glyphs[area][k].padding_p
+                 + (row->glyphs[area][k].type << 2));
+
+  return hashval;
+}
 
 /* Compute the pixel height and width of IT->glyph_row.
 
@@ -18035,17 +18052,7 @@
     }
 
   /* Compute a hash code for this row.  */
-  {
-    int area, i;
-    row->hash = 0;
-    for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
-      for (i = 0; i < row->used[area]; ++i)
-       row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
-                    + row->glyphs[area][i].u.val
-                    + row->glyphs[area][i].face_id
-                    + row->glyphs[area][i].padding_p
-                    + (row->glyphs[area][i].type << 2));
-  }
+  row->hash = row_hash (row);
 
   it->max_ascent = it->max_descent = 0;
   it->max_phys_ascent = it->max_phys_descent = 0;


reply via email to

[Prev in Thread] Current Thread [Next in Thread]