diff options
| author | Eli Zaretskii | 2014-02-20 19:40:56 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2014-02-20 19:40:56 +0200 |
| commit | 679f7827555eebb588131aebfcb9fdb959199904 (patch) | |
| tree | 194994cd6ca960faa0cb9767c31211fbd93aefd0 /src | |
| parent | dba8296c00f035fcf7e200e846a890445606f307 (diff) | |
| download | emacs-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/ChangeLog | 6 | ||||
| -rw-r--r-- | src/xdisp.c | 49 |
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 | ||
| 9 | 2014-02-20 Glenn Morris <rgm@gnu.org> | 15 | 2014-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 | } |