diff options
| author | Eli Zaretskii | 2011-07-16 20:17:01 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2011-07-16 20:17:01 +0300 |
| commit | 551918c187a781636fb437e71fcf7477afda8230 (patch) | |
| tree | 095c3405f3500547e534790610665ac336a123aa | |
| parent | c965adc5e0e9f30a3caeac4b5fa2023f89347b2e (diff) | |
| download | emacs-551918c187a781636fb437e71fcf7477afda8230.tar.gz emacs-551918c187a781636fb437e71fcf7477afda8230.zip | |
Fix a terrible slowdown in large fully fontified buffers.
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.
| -rw-r--r-- | src/ChangeLog | 7 | ||||
| -rw-r--r-- | src/xdisp.c | 32 |
2 files changed, 38 insertions, 1 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 21c394480bf..0114495838f 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | 2011-07-16 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * xdisp.c <cached_disp_pos, cached_disp_buffer, cached_disp_modiff>: | ||
| 4 | Cache for last found display string position. | ||
| 5 | (compute_display_string_pos): Return the cached position if asked | ||
| 6 | about the same buffer. | ||
| 7 | |||
| 1 | 2011-07-14 Eli Zaretskii <eliz@gnu.org> | 8 | 2011-07-14 Eli Zaretskii <eliz@gnu.org> |
| 2 | 9 | ||
| 3 | * bidi.c (bidi_cache_fetch_state, bidi_cache_search) | 10 | * 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) | |||
| 3137 | return endpos; | 3137 | return endpos; |
| 3138 | } | 3138 | } |
| 3139 | 3139 | ||
| 3140 | /* Record one cached display string position found recently by | ||
| 3141 | compute_display_string_pos. */ | ||
| 3142 | static EMACS_INT cached_disp_pos; | ||
| 3143 | static struct buffer *cached_disp_buffer; | ||
| 3144 | static int cached_disp_modiff; | ||
| 3145 | |||
| 3140 | /* Return the character position of a display string at or after | 3146 | /* Return the character position of a display string at or after |
| 3141 | position specified by POSITION. If no display string exists at or | 3147 | position specified by POSITION. If no display string exists at or |
| 3142 | after POSITION, return ZV. A display string is either an overlay | 3148 | after POSITION, return ZV. A display string is either an overlay |
| @@ -3158,6 +3164,7 @@ compute_display_string_pos (struct text_pos *position, | |||
| 3158 | EMACS_INT begb = string_p ? 0 : BEGV; | 3164 | EMACS_INT begb = string_p ? 0 : BEGV; |
| 3159 | EMACS_INT bufpos, charpos = CHARPOS (*position); | 3165 | EMACS_INT bufpos, charpos = CHARPOS (*position); |
| 3160 | struct text_pos tpos; | 3166 | struct text_pos tpos; |
| 3167 | struct buffer *b; | ||
| 3161 | 3168 | ||
| 3162 | if (charpos >= eob | 3169 | if (charpos >= eob |
| 3163 | /* We don't support display properties whose values are strings | 3170 | /* We don't support display properties whose values are strings |
| @@ -3167,6 +3174,23 @@ compute_display_string_pos (struct text_pos *position, | |||
| 3167 | || (string->s && !STRINGP (object))) | 3174 | || (string->s && !STRINGP (object))) |
| 3168 | return eob; | 3175 | return eob; |
| 3169 | 3176 | ||
| 3177 | /* Check the cached values. */ | ||
| 3178 | if (!STRINGP (object)) | ||
| 3179 | { | ||
| 3180 | if (NILP (object)) | ||
| 3181 | b = current_buffer; | ||
| 3182 | else | ||
| 3183 | b = XBUFFER (object); | ||
| 3184 | if (b == cached_disp_buffer | ||
| 3185 | && BUF_MODIFF (b) == cached_disp_modiff | ||
| 3186 | && charpos <= cached_disp_pos) | ||
| 3187 | return cached_disp_pos; | ||
| 3188 | |||
| 3189 | /* Record new values in the cache. */ | ||
| 3190 | cached_disp_buffer = b; | ||
| 3191 | cached_disp_modiff = BUF_MODIFF (b); | ||
| 3192 | } | ||
| 3193 | |||
| 3170 | /* If the character at CHARPOS is where the display string begins, | 3194 | /* If the character at CHARPOS is where the display string begins, |
| 3171 | return CHARPOS. */ | 3195 | return CHARPOS. */ |
| 3172 | pos = make_number (charpos); | 3196 | pos = make_number (charpos); |
| @@ -3182,7 +3206,11 @@ compute_display_string_pos (struct text_pos *position, | |||
| 3182 | spec)) | 3206 | spec)) |
| 3183 | && handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, | 3207 | && handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, |
| 3184 | frame_window_p)) | 3208 | frame_window_p)) |
| 3185 | return charpos; | 3209 | { |
| 3210 | if (!STRINGP (object)) | ||
| 3211 | cached_disp_pos = charpos; | ||
| 3212 | return charpos; | ||
| 3213 | } | ||
| 3186 | 3214 | ||
| 3187 | /* Look forward for the first character with a `display' property | 3215 | /* Look forward for the first character with a `display' property |
| 3188 | that will replace the underlying text when displayed. */ | 3216 | that will replace the underlying text when displayed. */ |
| @@ -3202,6 +3230,8 @@ compute_display_string_pos (struct text_pos *position, | |||
| 3202 | || !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, | 3230 | || !handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos, |
| 3203 | frame_window_p)); | 3231 | frame_window_p)); |
| 3204 | 3232 | ||
| 3233 | if (!STRINGP (object)) | ||
| 3234 | cached_disp_pos = CHARPOS (tpos); | ||
| 3205 | return CHARPOS (tpos); | 3235 | return CHARPOS (tpos); |
| 3206 | } | 3236 | } |
| 3207 | 3237 | ||