emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] trunk r115826: Fix bug #16265 with buffer caches when modi


From: Eli Zaretskii
Subject: [Emacs-diffs] trunk r115826: Fix bug #16265 with buffer caches when modifying text in indirect buffers.
Date: Wed, 01 Jan 2014 17:46:27 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 115826
revision-id: address@hidden
parent: address@hidden
fixes bug: http://debbugs.gnu.org/16265
committer: Eli Zaretskii <address@hidden>
branch nick: trunk
timestamp: Wed 2014-01-01 19:44:48 +0200
message:
  Fix bug #16265 with buffer caches when modifying text in indirect buffers.
  
   src/search.c (newline_cache_on_off, find_newline): In indirect
   buffers, use the newline cache of the base buffer.
   src/insdel.c (invalidate_buffer_caches): If BUF is an indirect
   buffer, invalidate the caches of its base buffer.
   src/indent.c (width_run_cache_on_off, compute_motion): In indirect
   buffers, use the width-run cache of the base buffer.
   src/xdisp.c (redisplay_window): When the window displays an indirect
   buffer, and the character widths in the display table have
   changed, invalidate the width-run cache of the corresponding base
   buffer.
   src/fileio.c (Finsert_file_contents): When invalidating the newline
   cache, consider the case of inserting into indirect buffer.
   src/bidi.c (bidi_paragraph_cache_on_off, bidi_find_paragraph_start):
   In indirect buffers, use the paragraph cache of the base buffer.
modified:
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/bidi.c                     bidi.c-20091231194348-rm8gzug639w0dpq5-1
  src/fileio.c                   fileio.c-20091113204419-o5vbwnq5f7feedwu-210
  src/indent.c                   indent.c-20091113204419-o5vbwnq5f7feedwu-181
  src/insdel.c                   insdel.c-20091113204419-o5vbwnq5f7feedwu-175
  src/search.c                   search.c-20091113204419-o5vbwnq5f7feedwu-473
  src/xdisp.c                    xdisp.c-20091113204419-o5vbwnq5f7feedwu-240
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2014-01-01 07:43:34 +0000
+++ b/src/ChangeLog     2014-01-01 17:44:48 +0000
@@ -1,3 +1,25 @@
+2014-01-01  Eli Zaretskii  <address@hidden>
+
+       * search.c (newline_cache_on_off, find_newline): In indirect
+       buffers, use the newline cache of the base buffer.
+
+       * insdel.c (invalidate_buffer_caches): If BUF is an indirect
+       buffer, invalidate the caches of its base buffer.  (Bug#16265)
+
+       * indent.c (width_run_cache_on_off, compute_motion): In indirect
+       buffers, use the width-run cache of the base buffer.
+
+       * xdisp.c (redisplay_window): When the window displays an indirect
+       buffer, and the character widths in the display table have
+       changed, invalidate the width-run cache of the corresponding base
+       buffer.
+
+       * fileio.c (Finsert_file_contents): When invalidating the newline
+       cache, consider the case of inserting into indirect buffer.
+
+       * bidi.c (bidi_paragraph_cache_on_off, bidi_find_paragraph_start):
+       In indirect buffers, use the paragraph cache of the base buffer.
+
 2013-12-31  Martin Rudalics  <address@hidden>
 
        * window.c (grow_mini_window): Fix last change.

=== modified file 'src/bidi.c'
--- a/src/bidi.c        2014-01-01 07:43:34 +0000
+++ b/src/bidi.c        2014-01-01 17:44:48 +0000
@@ -1100,20 +1100,44 @@
 static struct region_cache *
 bidi_paragraph_cache_on_off (void)
 {
+  struct buffer *cache_buffer = current_buffer;
+  bool indirect_p = false;
+
+  /* For indirect buffers, make sure to use the cache of their base
+     buffer.  */
+  if (cache_buffer->base_buffer)
+    {
+      cache_buffer = cache_buffer->base_buffer;
+      indirect_p = true;
+    }
+
+  /* Don't turn on or off the cache in the base buffer, if the value
+     of cache-long-scans of the base buffer is inconsistent with that.
+     This is because doing so will just make the cache pure overhead,
+     since if we turn it on via indirect buffer, it will be
+     immediately turned off by its base buffer.  */
   if (NILP (BVAR (current_buffer, cache_long_scans)))
     {
-      if (current_buffer->bidi_paragraph_cache)
+      if (!indirect_p
+         || NILP (BVAR (cache_buffer, cache_long_scans)))
        {
-         free_region_cache (current_buffer->bidi_paragraph_cache);
-         current_buffer->bidi_paragraph_cache = 0;
+         if (cache_buffer->bidi_paragraph_cache)
+           {
+             free_region_cache (cache_buffer->bidi_paragraph_cache);
+             cache_buffer->bidi_paragraph_cache = 0;
+           }
        }
       return NULL;
     }
   else
     {
-      if (!current_buffer->bidi_paragraph_cache)
-       current_buffer->bidi_paragraph_cache = new_region_cache ();
-      return current_buffer->bidi_paragraph_cache;
+      if (!indirect_p
+         || !NILP (BVAR (cache_buffer, cache_long_scans)))
+       {
+         if (!cache_buffer->bidi_paragraph_cache)
+           cache_buffer->bidi_paragraph_cache = new_region_cache ();
+       }
+      return cache_buffer->bidi_paragraph_cache;
     }
 }
 
@@ -1134,6 +1158,10 @@
   ptrdiff_t limit = ZV, limit_byte = ZV_BYTE;
   struct region_cache *bpc = bidi_paragraph_cache_on_off ();
   ptrdiff_t n = 0, oldpos = pos, next;
+  struct buffer *cache_buffer = current_buffer;
+
+  if (cache_buffer->base_buffer)
+    cache_buffer = cache_buffer->base_buffer;
 
   while (pos_byte > BEGV_BYTE
         && n++ < MAX_PARAGRAPH_SEARCH
@@ -1144,7 +1172,7 @@
         of the text over which we scan back includes
         paragraph_start_re?  */
       DEC_BOTH (pos, pos_byte);
-      if (bpc && region_cache_backward (current_buffer, bpc, pos, &next))
+      if (bpc && region_cache_backward (cache_buffer, bpc, pos, &next))
        {
          pos = next, pos_byte = CHAR_TO_BYTE (pos);
          break;
@@ -1155,7 +1183,7 @@
   if (n >= MAX_PARAGRAPH_SEARCH)
     pos = BEGV, pos_byte = BEGV_BYTE;
   if (bpc)
-    know_region_cache (current_buffer, bpc, pos, oldpos);
+    know_region_cache (cache_buffer, bpc, pos, oldpos);
   /* Positions returned by the region cache are not limited to
      BEGV..ZV range, so we limit them here.  */
   pos_byte = clip_to_bounds (BEGV_BYTE, pos_byte, ZV_BYTE);

=== modified file 'src/fileio.c'
--- a/src/fileio.c      2014-01-01 07:43:34 +0000
+++ b/src/fileio.c      2014-01-01 17:44:48 +0000
@@ -4496,7 +4496,11 @@
   /* We made a lot of deletions and insertions above, so invalidate
      the newline cache for the entire region of the inserted
      characters.  */
-  if (current_buffer->newline_cache)
+  if (current_buffer->base_buffer && 
current_buffer->base_buffer->newline_cache)
+    invalidate_region_cache (current_buffer->base_buffer,
+                             current_buffer->base_buffer->newline_cache,
+                             PT - BEG, Z - PT - inserted);
+  else if (current_buffer->newline_cache)
     invalidate_region_cache (current_buffer,
                              current_buffer->newline_cache,
                              PT - BEG, Z - PT - inserted);

=== modified file 'src/indent.c'
--- a/src/indent.c      2014-01-01 07:43:34 +0000
+++ b/src/indent.c      2014-01-01 17:44:48 +0000
@@ -144,30 +144,51 @@
 /* Allocate or free the width run cache, as requested by the
    current state of current_buffer's cache_long_scans variable.  */
 
-static void
+static struct region_cache *
 width_run_cache_on_off (void)
 {
+  struct buffer *cache_buffer = current_buffer;
+  bool indirect_p = false;
+
+  if (cache_buffer->base_buffer)
+    {
+      cache_buffer = cache_buffer->base_buffer;
+      indirect_p = true;
+    }
+
   if (NILP (BVAR (current_buffer, cache_long_scans))
       /* And, for the moment, this feature doesn't work on multibyte
          characters.  */
       || !NILP (BVAR (current_buffer, enable_multibyte_characters)))
     {
-      /* It should be off.  */
-      if (current_buffer->width_run_cache)
-        {
-          free_region_cache (current_buffer->width_run_cache);
-          current_buffer->width_run_cache = 0;
-          bset_width_table (current_buffer, Qnil);
+      if (!indirect_p
+         || NILP (BVAR (cache_buffer, cache_long_scans))
+         || !NILP (BVAR (cache_buffer, enable_multibyte_characters)))
+       {
+         /* It should be off.  */
+         if (cache_buffer->width_run_cache)
+           {
+             free_region_cache (cache_buffer->width_run_cache);
+             cache_buffer->width_run_cache = 0;
+             bset_width_table (current_buffer, Qnil);
+           }
         }
+      return NULL;
     }
   else
     {
-      /* It should be on.  */
-      if (current_buffer->width_run_cache == 0)
-        {
-          current_buffer->width_run_cache = new_region_cache ();
-          recompute_width_table (current_buffer, buffer_display_table ());
-        }
+      if (!indirect_p
+         || (!NILP (BVAR (cache_buffer, cache_long_scans))
+             && NILP (BVAR (cache_buffer, enable_multibyte_characters))))
+       {
+         /* It should be on.  */
+         if (cache_buffer->width_run_cache == 0)
+           {
+             cache_buffer->width_run_cache = new_region_cache ();
+             recompute_width_table (current_buffer, buffer_display_table ());
+           }
+       }
+      return cache_buffer->width_run_cache;
     }
 }
 
@@ -1128,12 +1149,16 @@
   EMACS_INT contin_hpos;       /* HPOS of last column of continued line.  */
   int prev_tab_offset;         /* Previous tab offset.  */
   int continuation_glyph_width;
+  struct buffer *cache_buffer = current_buffer;
+  struct region_cache *width_cache;
 
   struct composition_it cmp_it;
 
   XSETWINDOW (window, win);
 
-  width_run_cache_on_off ();
+  if (cache_buffer->base_buffer)
+    cache_buffer = cache_buffer->base_buffer;
+  width_cache = width_run_cache_on_off ();
   if (dp == buffer_display_table ())
     width_table = (VECTORP (BVAR (current_buffer, width_table))
                    ? XVECTOR (BVAR (current_buffer, width_table))->contents
@@ -1404,13 +1429,11 @@
 
       /* Consult the width run cache to see if we can avoid inspecting
          the text character-by-character.  */
-      if (current_buffer->width_run_cache && pos >= next_width_run)
+      if (width_cache && pos >= next_width_run)
         {
           ptrdiff_t run_end;
           int common_width
-            = region_cache_forward (current_buffer,
-                                    current_buffer->width_run_cache,
-                                    pos, &run_end);
+            = region_cache_forward (cache_buffer, width_cache, pos, &run_end);
 
           /* A width of zero means the character's width varies (like
              a tab), is meaningless (like a newline), or we just don't
@@ -1486,7 +1509,7 @@
          pos++, pos_byte++;
 
          /* Perhaps add some info to the width_run_cache.  */
-         if (current_buffer->width_run_cache)
+         if (width_cache)
            {
              /* Is this character part of the current run?  If so, extend
                 the run.  */
@@ -1502,8 +1525,7 @@
                     (Currently, we only cache runs of width == 1).  */
                  if (width_run_start < width_run_end
                      && width_run_width == 1)
-                   know_region_cache (current_buffer,
-                                      current_buffer->width_run_cache,
+                   know_region_cache (cache_buffer, width_cache,
                                       width_run_start, width_run_end);
 
                  /* Start recording a new width run.  */
@@ -1639,10 +1661,10 @@
  after_loop:
 
   /* Remember any final width run in the cache.  */
-  if (current_buffer->width_run_cache
+  if (width_cache
       && width_run_width == 1
       && width_run_start < width_run_end)
-    know_region_cache (current_buffer, current_buffer->width_run_cache,
+    know_region_cache (cache_buffer, width_cache,
                        width_run_start, width_run_end);
 
   val_compute_motion.bufpos = pos;

=== modified file 'src/insdel.c'
--- a/src/insdel.c      2014-01-01 07:43:34 +0000
+++ b/src/insdel.c      2014-01-01 17:44:48 +0000
@@ -1878,6 +1878,10 @@
 void
 invalidate_buffer_caches (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
 {
+  /* Indirect buffers usually have their caches set to NULL, but we
+     need to consider the caches of their base buffer.  */
+  if (buf->base_buffer)
+    buf = buf->base_buffer;
   if (buf->newline_cache)
     invalidate_region_cache (buf,
                              buf->newline_cache,

=== modified file 'src/search.c'
--- a/src/search.c      2014-01-01 07:43:34 +0000
+++ b/src/search.c      2014-01-01 17:44:48 +0000
@@ -602,23 +602,47 @@
    Otherwise, make sure it's off.
    This is our cheezy way of associating an action with the change of
    state of a buffer-local variable.  */
-static void
+static struct region_cache *
 newline_cache_on_off (struct buffer *buf)
 {
+  struct buffer *base_buf = buf;
+  bool indirect_p = false;
+
+  if (buf->base_buffer)
+    {
+      base_buf = buf->base_buffer;
+      indirect_p = true;
+    }
+
+  /* Don't turn on or off the cache in the base buffer, if the value
+     of cache-long-scans of the base buffer is inconsistent with that.
+     This is because doing so will just make the cache pure overhead,
+     since if we turn it on via indirect buffer, it will be
+     immediately turned off by its base buffer.  */
   if (NILP (BVAR (buf, cache_long_scans)))
     {
-      /* It should be off.  */
-      if (buf->newline_cache)
-        {
-          free_region_cache (buf->newline_cache);
-          buf->newline_cache = 0;
-        }
+      if (!indirect_p
+         || NILP (BVAR (base_buf, cache_long_scans)))
+       {
+         /* It should be off.  */
+         if (base_buf->newline_cache)
+           {
+             free_region_cache (base_buf->newline_cache);
+             base_buf->newline_cache = 0;
+           }
+       }
+      return NULL;
     }
   else
     {
-      /* It should be on.  */
-      if (buf->newline_cache == 0)
-        buf->newline_cache = new_region_cache ();
+      if (!indirect_p
+         || !NILP (BVAR (base_buf, cache_long_scans)))
+       {
+         /* It should be on.  */
+         if (base_buf->newline_cache == 0)
+           base_buf->newline_cache = new_region_cache ();
+       }
+      return base_buf->newline_cache;
     }
 }
 
@@ -653,6 +677,7 @@
 {
   struct region_cache *newline_cache;
   int direction;
+  struct buffer *cache_buffer;
 
   if (count > 0)
     {
@@ -669,8 +694,11 @@
   if (end_byte == -1)
     end_byte = CHAR_TO_BYTE (end);
 
-  newline_cache_on_off (current_buffer);
-  newline_cache = current_buffer->newline_cache;
+  newline_cache = newline_cache_on_off (current_buffer);
+  if (current_buffer->base_buffer)
+    cache_buffer = current_buffer->base_buffer;
+  else
+    cache_buffer = current_buffer;
 
   if (shortage != 0)
     *shortage = 0;
@@ -694,7 +722,7 @@
             ptrdiff_t next_change;
             immediate_quit = 0;
             while (region_cache_forward
-                   (current_buffer, newline_cache, start, &next_change))
+                   (cache_buffer, newline_cache, start, &next_change))
               start = next_change;
             immediate_quit = allow_quit;
 
@@ -738,7 +766,7 @@
                  this line's region is free of them. */
               if (newline_cache)
                {
-                 know_region_cache (current_buffer, newline_cache,
+                 know_region_cache (cache_buffer, newline_cache,
                                     BYTE_TO_CHAR (lim_byte + cursor),
                                     BYTE_TO_CHAR (lim_byte + next));
                  /* know_region_cache can relocate buffer text.  */
@@ -774,7 +802,7 @@
             ptrdiff_t next_change;
             immediate_quit = 0;
             while (region_cache_backward
-                   (current_buffer, newline_cache, start, &next_change))
+                   (cache_buffer, newline_cache, start, &next_change))
               start = next_change;
             immediate_quit = allow_quit;
 
@@ -814,7 +842,7 @@
                  this line's region is free of them. */
               if (newline_cache)
                {
-                 know_region_cache (current_buffer, newline_cache,
+                 know_region_cache (cache_buffer, newline_cache,
                                     BYTE_TO_CHAR (ceiling_byte + prev + 1),
                                     BYTE_TO_CHAR (ceiling_byte + cursor));
                  /* know_region_cache can relocate buffer text.  */

=== modified file 'src/xdisp.c'
--- a/src/xdisp.c       2014-01-01 07:43:34 +0000
+++ b/src/xdisp.c       2014-01-01 17:44:48 +0000
@@ -15767,16 +15767,20 @@
      this may be a bit late to catch such changes, but the rest of
      redisplay goes (non-fatally) haywire when the display table is
      changed, so why should we worry about doing any better?  */
-  if (current_buffer->width_run_cache)
+  if (current_buffer->width_run_cache
+      || (current_buffer->base_buffer
+         && current_buffer->base_buffer->width_run_cache))
     {
       struct Lisp_Char_Table *disptab = buffer_display_table ();
 
       if (! disptab_matches_widthtab
          (disptab, XVECTOR (BVAR (current_buffer, width_table))))
         {
-          invalidate_region_cache (current_buffer,
-                                   current_buffer->width_run_cache,
-                                   BEG, Z);
+         struct buffer *buf = current_buffer;
+
+         if (buf->base_buffer)
+           buf = buf->base_buffer;
+          invalidate_region_cache (buf, buf->width_run_cache, BEG, Z);
           recompute_width_table (current_buffer, disptab);
         }
     }


reply via email to

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