]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix a terrible slowdown in large fully fontified buffers.
authorEli Zaretskii <eliz@gnu.org>
Sat, 16 Jul 2011 17:17:01 +0000 (20:17 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sat, 16 Jul 2011 17:17:01 +0000 (20:17 +0300)
 src/xdisp.c <cached_disp_pos, cached_disp_buffer, cached_disp_modiff>:
 Cache for last found display string position.
 (compute_display_string_pos): Return the cached position if asked
 about the same buffer.

src/ChangeLog
src/xdisp.c

index 21c394480bf3f6b03041b1f8fcc2acca13f2f9e9..0114495838f70a7158b261caccf731aa4cf9619a 100644 (file)
@@ -1,3 +1,10 @@
+2011-07-16  Eli Zaretskii  <eliz@gnu.org>
+
+       * xdisp.c <cached_disp_pos, cached_disp_buffer, cached_disp_modiff>:
+       Cache for last found display string position.
+       (compute_display_string_pos): Return the cached position if asked
+       about the same buffer.
+
 2011-07-14  Eli Zaretskii  <eliz@gnu.org>
 
        * bidi.c (bidi_cache_fetch_state, bidi_cache_search)
index cef2fe6df7bef734424f0c51eb3bb70e2e076d06..1ddd78caa5d51457d449441a47a4cf0c1066508e 100644 (file)
@@ -3137,6 +3137,12 @@ next_overlay_change (EMACS_INT pos)
   return endpos;
 }
 
+/* Record one cached display string position found recently by
+   compute_display_string_pos.  */
+static EMACS_INT cached_disp_pos;
+static struct buffer *cached_disp_buffer;
+static int cached_disp_modiff;
+
 /* Return the character position of a display string at or after
    position specified by POSITION.  If no display string exists at or
    after POSITION, return ZV.  A display string is either an overlay
@@ -3158,6 +3164,7 @@ compute_display_string_pos (struct text_pos *position,
   EMACS_INT begb = string_p ? 0 : BEGV;
   EMACS_INT bufpos, charpos = CHARPOS (*position);
   struct text_pos tpos;
+  struct buffer *b;
 
   if (charpos >= eob
       /* We don't support display properties whose values are strings
@@ -3167,6 +3174,23 @@ compute_display_string_pos (struct text_pos *position,
       || (string->s && !STRINGP (object)))
     return eob;
 
+  /* Check the cached values.  */
+  if (!STRINGP (object))
+    {
+      if (NILP (object))
+       b = current_buffer;
+      else
+       b = XBUFFER (object);
+      if (b == cached_disp_buffer
+         && BUF_MODIFF (b) == cached_disp_modiff
+         && charpos <= cached_disp_pos)
+       return cached_disp_pos;
+
+      /* Record new values in the cache.  */
+      cached_disp_buffer = b;
+      cached_disp_modiff = BUF_MODIFF (b);
+    }
+
   /* If the character at CHARPOS is where the display string begins,
      return CHARPOS.  */
   pos = make_number (charpos);
@@ -3182,7 +3206,11 @@ compute_display_string_pos (struct text_pos *position,
                  spec))
       && handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
                              frame_window_p))
-    return charpos;
+    {
+      if (!STRINGP (object))
+       cached_disp_pos = charpos;
+      return charpos;
+    }
 
   /* Look forward for the first character with a `display' property
      that will replace the underlying text when displayed.  */
@@ -3202,6 +3230,8 @@ compute_display_string_pos (struct text_pos *position,
           || !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
                                    frame_window_p));
 
+  if (!STRINGP (object))
+    cached_disp_pos = CHARPOS (tpos);
   return CHARPOS (tpos);
 }