aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2014-02-20 19:40:56 +0200
committerEli Zaretskii2014-02-20 19:40:56 +0200
commit679f7827555eebb588131aebfcb9fdb959199904 (patch)
tree194994cd6ca960faa0cb9767c31211fbd93aefd0 /src
parentdba8296c00f035fcf7e200e846a890445606f307 (diff)
downloademacs-679f7827555eebb588131aebfcb9fdb959199904.tar.gz
emacs-679f7827555eebb588131aebfcb9fdb959199904.zip
Fix excessive calls to bidi_shelve_cache reported in bug #15555.
src/xdisp.c (move_it_in_display_line_to): Save the iterator state in ppos_it only once per call. Reimplement the method used to return to the best candidate position if all the positions found in display line are beyond TO_CHARPOS. This cuts down the number of calls to bidi_shelve_cache, which moves a lot of stuff when lines are long and include bidirectional text.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog6
-rw-r--r--src/xdisp.c49
2 files changed, 38 insertions, 17 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 3c063ca3c0b..4bb47197106 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -5,6 +5,12 @@
5 (try_cursor_movement): Don't use cursor position if 5 (try_cursor_movement): Don't use cursor position if
6 set_cursor_from_row failed to compute it. This avoids assertion 6 set_cursor_from_row failed to compute it. This avoids assertion
7 violations in MATRIX_ROW. 7 violations in MATRIX_ROW.
8 (move_it_in_display_line_to): Save the iterator state in ppos_it
9 only once per call. Reimplement the method used to return to the
10 best candidate position if all the positions found in display line
11 are beyond TO_CHARPOS. This cuts down the number of calls to
12 bidi_shelve_cache, which moves a lot of stuff when lines are long
13 and include bidirectional text. (Bug#15555)
8 14
92014-02-20 Glenn Morris <rgm@gnu.org> 152014-02-20 Glenn Morris <rgm@gnu.org>
10 16
diff --git a/src/xdisp.c b/src/xdisp.c
index 94dd65c5d0b..840ff1288e5 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -8313,7 +8313,7 @@ move_it_in_display_line_to (struct it *it,
8313 void *ppos_data = NULL; 8313 void *ppos_data = NULL;
8314 int may_wrap = 0; 8314 int may_wrap = 0;
8315 enum it_method prev_method = it->method; 8315 enum it_method prev_method = it->method;
8316 ptrdiff_t prev_pos = IT_CHARPOS (*it); 8316 ptrdiff_t closest_pos, prev_pos = IT_CHARPOS (*it);
8317 int saw_smaller_pos = prev_pos < to_charpos; 8317 int saw_smaller_pos = prev_pos < to_charpos;
8318 8318
8319 /* Don't produce glyphs in produce_glyphs. */ 8319 /* Don't produce glyphs in produce_glyphs. */
@@ -8330,16 +8330,21 @@ move_it_in_display_line_to (struct it *it,
8330 atx_it.sp = -1; 8330 atx_it.sp = -1;
8331 8331
8332 /* Use ppos_it under bidi reordering to save a copy of IT for the 8332 /* Use ppos_it under bidi reordering to save a copy of IT for the
8333 position > CHARPOS that is the closest to CHARPOS. We restore 8333 initial position. We restore that position in IT when we have
8334 that position in IT when we have scanned the entire display line 8334 scanned the entire display line without finding a match for
8335 without finding a match for CHARPOS and all the character 8335 TO_CHARPOS and all the character positions are greater than
8336 positions are greater than CHARPOS. */ 8336 TO_CHARPOS. We then restart the scan from the initial position,
8337 and stop at CLOSEST_POS, which is a position > TO_CHARPOS that is
8338 the closest to TO_CHARPOS. */
8337 if (it->bidi_p) 8339 if (it->bidi_p)
8338 { 8340 {
8339 SAVE_IT (ppos_it, *it, ppos_data);
8340 SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
8341 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos) 8341 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8342 SAVE_IT (ppos_it, *it, ppos_data); 8342 {
8343 SAVE_IT (ppos_it, *it, ppos_data);
8344 closest_pos = IT_CHARPOS (*it);
8345 }
8346 else
8347 closest_pos = ZV;
8343 } 8348 }
8344 8349
8345#define BUFFER_POS_REACHED_P() \ 8350#define BUFFER_POS_REACHED_P() \
@@ -8483,8 +8488,8 @@ move_it_in_display_line_to (struct it *it,
8483 if (it->bidi_p 8488 if (it->bidi_p
8484 && (op & MOVE_TO_POS) 8489 && (op & MOVE_TO_POS)
8485 && IT_CHARPOS (*it) > to_charpos 8490 && IT_CHARPOS (*it) > to_charpos
8486 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it)) 8491 && IT_CHARPOS (*it) < closest_pos)
8487 SAVE_IT (ppos_it, *it, ppos_data); 8492 closest_pos = IT_CHARPOS (*it);
8488 continue; 8493 continue;
8489 } 8494 }
8490 8495
@@ -8706,9 +8711,11 @@ move_it_in_display_line_to (struct it *it,
8706 { 8711 {
8707 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos) 8712 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
8708 { 8713 {
8709 if (IT_CHARPOS (ppos_it) < ZV) 8714 if (closest_pos < ZV)
8710 { 8715 {
8711 RESTORE_IT (it, &ppos_it, ppos_data); 8716 RESTORE_IT (it, &ppos_it, ppos_data);
8717 move_it_in_display_line_to (it, closest_pos, -1,
8718 MOVE_TO_POS);
8712 result = MOVE_POS_MATCH_OR_ZV; 8719 result = MOVE_POS_MATCH_OR_ZV;
8713 } 8720 }
8714 else 8721 else
@@ -8738,8 +8745,8 @@ move_it_in_display_line_to (struct it *it,
8738 if (it->bidi_p 8745 if (it->bidi_p
8739 && (op & MOVE_TO_POS) 8746 && (op & MOVE_TO_POS)
8740 && IT_CHARPOS (*it) >= to_charpos 8747 && IT_CHARPOS (*it) >= to_charpos
8741 && IT_CHARPOS (*it) < IT_CHARPOS (ppos_it)) 8748 && IT_CHARPOS (*it) < closest_pos)
8742 SAVE_IT (ppos_it, *it, ppos_data); 8749 closest_pos = IT_CHARPOS (*it);
8743 8750
8744 /* Stop if lines are truncated and IT's current x-position is 8751 /* Stop if lines are truncated and IT's current x-position is
8745 past the right edge of the window now. */ 8752 past the right edge of the window now. */
@@ -8765,8 +8772,13 @@ move_it_in_display_line_to (struct it *it,
8765 && IT_CHARPOS (*it) > to_charpos)) 8772 && IT_CHARPOS (*it) > to_charpos))
8766 { 8773 {
8767 if (it->bidi_p 8774 if (it->bidi_p
8768 && !at_eob_p && IT_CHARPOS (ppos_it) < ZV) 8775 && !BUFFER_POS_REACHED_P ()
8769 RESTORE_IT (it, &ppos_it, ppos_data); 8776 && !at_eob_p && closest_pos < ZV)
8777 {
8778 RESTORE_IT (it, &ppos_it, ppos_data);
8779 move_it_in_display_line_to (it, closest_pos, -1,
8780 MOVE_TO_POS);
8781 }
8770 result = MOVE_POS_MATCH_OR_ZV; 8782 result = MOVE_POS_MATCH_OR_ZV;
8771 break; 8783 break;
8772 } 8784 }
@@ -8780,8 +8792,11 @@ move_it_in_display_line_to (struct it *it,
8780 && !saw_smaller_pos 8792 && !saw_smaller_pos
8781 && IT_CHARPOS (*it) > to_charpos) 8793 && IT_CHARPOS (*it) > to_charpos)
8782 { 8794 {
8783 if (IT_CHARPOS (ppos_it) < ZV) 8795 if (closest_pos < ZV)
8784 RESTORE_IT (it, &ppos_it, ppos_data); 8796 {
8797 RESTORE_IT (it, &ppos_it, ppos_data);
8798 move_it_in_display_line_to (it, closest_pos, -1, MOVE_TO_POS);
8799 }
8785 result = MOVE_POS_MATCH_OR_ZV; 8800 result = MOVE_POS_MATCH_OR_ZV;
8786 break; 8801 break;
8787 } 8802 }