From 551918c187a781636fb437e71fcf7477afda8230 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 16 Jul 2011 20:17:01 +0300 Subject: [PATCH] Fix a terrible slowdown in large fully fontified buffers. src/xdisp.c : Cache for last found display string position. (compute_display_string_pos): Return the cached position if asked about the same buffer. --- src/ChangeLog | 7 +++++++ src/xdisp.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/ChangeLog b/src/ChangeLog index 21c394480bf..0114495838f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2011-07-16 Eli Zaretskii + + * xdisp.c : + 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 * bidi.c (bidi_cache_fetch_state, bidi_cache_search) diff --git a/src/xdisp.c b/src/xdisp.c index cef2fe6df7b..1ddd78caa5d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -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); } -- 2.39.2