Commit 679f7827 authored by Eli Zaretskii's avatar Eli Zaretskii
Browse files

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.
parent dba8296c
...@@ -5,6 +5,12 @@ ...@@ -5,6 +5,12 @@
(try_cursor_movement): Don't use cursor position if (try_cursor_movement): Don't use cursor position if
set_cursor_from_row failed to compute it. This avoids assertion set_cursor_from_row failed to compute it. This avoids assertion
violations in MATRIX_ROW. violations in MATRIX_ROW.
(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. (Bug#15555)
2014-02-20 Glenn Morris <rgm@gnu.org> 2014-02-20 Glenn Morris <rgm@gnu.org>
......
...@@ -8313,7 +8313,7 @@ move_it_in_display_line_to (struct it *it, ...@@ -8313,7 +8313,7 @@ move_it_in_display_line_to (struct it *it,
void *ppos_data = NULL; void *ppos_data = NULL;
int may_wrap = 0; int may_wrap = 0;
enum it_method prev_method = it->method; enum it_method prev_method = it->method;
ptrdiff_t prev_pos = IT_CHARPOS (*it); ptrdiff_t closest_pos, prev_pos = IT_CHARPOS (*it);
int saw_smaller_pos = prev_pos < to_charpos; int saw_smaller_pos = prev_pos < to_charpos;
   
/* Don't produce glyphs in produce_glyphs. */ /* Don't produce glyphs in produce_glyphs. */
...@@ -8330,16 +8330,21 @@ move_it_in_display_line_to (struct it *it, ...@@ -8330,16 +8330,21 @@ move_it_in_display_line_to (struct it *it,
atx_it.sp = -1; atx_it.sp = -1;
   
/* Use ppos_it under bidi reordering to save a copy of IT for the /* Use ppos_it under bidi reordering to save a copy of IT for the
position > CHARPOS that is the closest to CHARPOS. We restore initial position. We restore that position in IT when we have
that position in IT when we have scanned the entire display line scanned the entire display line without finding a match for
without finding a match for CHARPOS and all the character TO_CHARPOS and all the character positions are greater than
positions are greater than CHARPOS. */ TO_CHARPOS. We then restart the scan from the initial position,
and stop at CLOSEST_POS, which is a position > TO_CHARPOS that is
the closest to TO_CHARPOS. */
if (it->bidi_p) if (it->bidi_p)
{ {
SAVE_IT (ppos_it, *it, ppos_data);
SET_TEXT_POS (ppos_it.current.pos, ZV, ZV_BYTE);
if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos) if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
SAVE_IT (ppos_it, *it, ppos_data); {
SAVE_IT (ppos_it, *it, ppos_data);
closest_pos = IT_CHARPOS (*it);
}
else
closest_pos = ZV;
} }
   
#define BUFFER_POS_REACHED_P() \ #define BUFFER_POS_REACHED_P() \
...@@ -8483,8 +8488,8 @@ move_it_in_display_line_to (struct it *it, ...@@ -8483,8 +8488,8 @@ move_it_in_display_line_to (struct it *it,
if (it->bidi_p if (it->bidi_p
&& (op & MOVE_TO_POS) && (op & MOVE_TO_POS)
&& IT_CHARPOS (*it) > to_charpos && IT_CHARPOS (*it) > to_charpos
&& IT_CHARPOS (*it) < IT_CHARPOS (ppos_it)) && IT_CHARPOS (*it) < closest_pos)
SAVE_IT (ppos_it, *it, ppos_data); closest_pos = IT_CHARPOS (*it);
continue; continue;
} }
   
...@@ -8706,9 +8711,11 @@ move_it_in_display_line_to (struct it *it, ...@@ -8706,9 +8711,11 @@ move_it_in_display_line_to (struct it *it,
{ {
if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos) if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
{ {
if (IT_CHARPOS (ppos_it) < ZV) if (closest_pos < ZV)
{ {
RESTORE_IT (it, &ppos_it, ppos_data); RESTORE_IT (it, &ppos_it, ppos_data);
move_it_in_display_line_to (it, closest_pos, -1,
MOVE_TO_POS);
result = MOVE_POS_MATCH_OR_ZV; result = MOVE_POS_MATCH_OR_ZV;
} }
else else
...@@ -8738,8 +8745,8 @@ move_it_in_display_line_to (struct it *it, ...@@ -8738,8 +8745,8 @@ move_it_in_display_line_to (struct it *it,
if (it->bidi_p if (it->bidi_p
&& (op & MOVE_TO_POS) && (op & MOVE_TO_POS)
&& IT_CHARPOS (*it) >= to_charpos && IT_CHARPOS (*it) >= to_charpos
&& IT_CHARPOS (*it) < IT_CHARPOS (ppos_it)) && IT_CHARPOS (*it) < closest_pos)
SAVE_IT (ppos_it, *it, ppos_data); closest_pos = IT_CHARPOS (*it);
   
/* Stop if lines are truncated and IT's current x-position is /* Stop if lines are truncated and IT's current x-position is
past the right edge of the window now. */ past the right edge of the window now. */
...@@ -8765,8 +8772,13 @@ move_it_in_display_line_to (struct it *it, ...@@ -8765,8 +8772,13 @@ move_it_in_display_line_to (struct it *it,
&& IT_CHARPOS (*it) > to_charpos)) && IT_CHARPOS (*it) > to_charpos))
{ {
if (it->bidi_p if (it->bidi_p
&& !at_eob_p && IT_CHARPOS (ppos_it) < ZV) && !BUFFER_POS_REACHED_P ()
RESTORE_IT (it, &ppos_it, ppos_data); && !at_eob_p && closest_pos < ZV)
{
RESTORE_IT (it, &ppos_it, ppos_data);
move_it_in_display_line_to (it, closest_pos, -1,
MOVE_TO_POS);
}
result = MOVE_POS_MATCH_OR_ZV; result = MOVE_POS_MATCH_OR_ZV;
break; break;
} }
...@@ -8780,8 +8792,11 @@ move_it_in_display_line_to (struct it *it, ...@@ -8780,8 +8792,11 @@ move_it_in_display_line_to (struct it *it,
&& !saw_smaller_pos && !saw_smaller_pos
&& IT_CHARPOS (*it) > to_charpos) && IT_CHARPOS (*it) > to_charpos)
{ {
if (IT_CHARPOS (ppos_it) < ZV) if (closest_pos < ZV)
RESTORE_IT (it, &ppos_it, ppos_data); {
RESTORE_IT (it, &ppos_it, ppos_data);
move_it_in_display_line_to (it, closest_pos, -1, MOVE_TO_POS);
}
result = MOVE_POS_MATCH_OR_ZV; result = MOVE_POS_MATCH_OR_ZV;
break; break;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment