aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2011-08-05 14:04:44 +0300
committerEli Zaretskii2011-08-05 14:04:44 +0300
commit5009803bda518652cc6f4b9fba02c0aed185c2a3 (patch)
tree5d0443887455129a793cadd52f03f740ec5230da /src
parente2e2423bf2fe3cda60737f20aeafaff64d38b35e (diff)
parent35928349678bc6ed8f621fe7d4da6a9a3fb3579d (diff)
downloademacs-5009803bda518652cc6f4b9fba02c0aed185c2a3.tar.gz
emacs-5009803bda518652cc6f4b9fba02c0aed185c2a3.zip
Fix bug #9221 with memory leak in bidi display.
Add code to monitor memory allocation for bidi cache shelving. src/xdisp.c (display_line): Release buffer allocated for shelved bidi cache. src/bidi.c (bidi_shelve_cache, bidi_unshelve_cache): Track total amount allocated this far in `bidi_cache_total_alloc'. (bidi_unshelve_cache): Accept an additional argument JUST_FREE; if non-zero, only free the data buffer without restoring the cache contents. All callers changed. src/dispextern.h (bidi_unshelve_cache): Update prototype. src/xdisp.c (SAVE_IT, pos_visible_p, move_it_in_display_line_to) (move_it_in_display_line, move_it_to) (move_it_vertically_backward, move_it_by_lines): Replace the call to xfree to an equivalent call to bidi_unshelve_cache. (move_it_in_display_line_to): Fix logic of returning MOVE_POS_MATCH_OR_ZV in the bidi case.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog20
-rw-r--r--src/bidi.c76
-rw-r--r--src/dispextern.h2
-rw-r--r--src/dispnew.c2
-rw-r--r--src/indent.c2
-rw-r--r--src/window.c18
-rw-r--r--src/xdisp.c53
7 files changed, 110 insertions, 63 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 5861ee6c48b..3ac958e0311 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,25 @@
12011-08-05 Eli Zaretskii <eliz@gnu.org> 12011-08-05 Eli Zaretskii <eliz@gnu.org>
2 2
3 *xdisp.c (display_line): Release buffer allocated for shelved bidi
4 cache. (Bug#9221)
5
6 * bidi.c (bidi_shelve_cache, bidi_unshelve_cache): Track total
7 amount allocated this far in `bidi_cache_total_alloc'.
8 (bidi_unshelve_cache): Accept an additional argument JUST_FREE; if
9 non-zero, only free the data buffer without restoring the cache
10 contents. All callers changed.
11
12 * dispextern.h (bidi_unshelve_cache): Update prototype.
13
14 * xdisp.c (SAVE_IT, pos_visible_p, move_it_in_display_line_to)
15 (move_it_in_display_line, move_it_to)
16 (move_it_vertically_backward, move_it_by_lines): Replace the call
17 to xfree to an equivalent call to bidi_unshelve_cache.
18 (move_it_in_display_line_to): Fix logic of returning
19 MOVE_POS_MATCH_OR_ZV in the bidi case.
20
212011-08-05 Eli Zaretskii <eliz@gnu.org>
22
3 * xdisp.c (set_cursor_from_row): Prefer the candidate glyph that 23 * xdisp.c (set_cursor_from_row): Prefer the candidate glyph that
4 came from a string character with a `cursor' property. (Bug#9229) 24 came from a string character with a `cursor' property. (Bug#9229)
5 25
diff --git a/src/bidi.c b/src/bidi.c
index ae5143b37e0..00a6aeef954 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -620,12 +620,15 @@ bidi_pop_it (struct bidi_it *bidi_it)
620 bidi_cache_last_idx = -1; 620 bidi_cache_last_idx = -1;
621} 621}
622 622
623ptrdiff_t bidi_cache_total_alloc;
624
623/* Stash away a copy of the cache and its control variables. */ 625/* Stash away a copy of the cache and its control variables. */
624void * 626void *
625bidi_shelve_cache (void) 627bidi_shelve_cache (void)
626{ 628{
627 unsigned char *databuf; 629 unsigned char *databuf;
628 630
631 /* Empty cache. */
629 if (bidi_cache_idx == 0) 632 if (bidi_cache_idx == 0)
630 return NULL; 633 return NULL;
631 634
@@ -634,6 +637,12 @@ bidi_shelve_cache (void)
634 + sizeof (bidi_cache_start_stack) 637 + sizeof (bidi_cache_start_stack)
635 + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) 638 + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start)
636 + sizeof (bidi_cache_last_idx)); 639 + sizeof (bidi_cache_last_idx));
640 bidi_cache_total_alloc +=
641 sizeof (bidi_cache_idx) + bidi_cache_idx * sizeof (struct bidi_it)
642 + sizeof (bidi_cache_start_stack)
643 + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start)
644 + sizeof (bidi_cache_last_idx);
645
637 memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx)); 646 memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx));
638 memcpy (databuf + sizeof (bidi_cache_idx), 647 memcpy (databuf + sizeof (bidi_cache_idx),
639 bidi_cache, bidi_cache_idx * sizeof (struct bidi_it)); 648 bidi_cache, bidi_cache_idx * sizeof (struct bidi_it));
@@ -659,7 +668,7 @@ bidi_shelve_cache (void)
659 668
660/* Restore the cache state from a copy stashed away by bidi_shelve_cache. */ 669/* Restore the cache state from a copy stashed away by bidi_shelve_cache. */
661void 670void
662bidi_unshelve_cache (void *databuf) 671bidi_unshelve_cache (void *databuf, int just_free)
663{ 672{
664 unsigned char *p = databuf; 673 unsigned char *p = databuf;
665 674
@@ -672,30 +681,47 @@ bidi_unshelve_cache (void *databuf)
672 } 681 }
673 else 682 else
674 { 683 {
675 memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx)); 684 if (just_free)
676 bidi_cache_ensure_space (bidi_cache_idx); 685 {
677 memcpy (bidi_cache, p + sizeof (bidi_cache_idx), 686 ptrdiff_t idx;
678 bidi_cache_idx * sizeof (struct bidi_it)); 687
679 memcpy (bidi_cache_start_stack, 688 memcpy (&idx, p, sizeof (bidi_cache_idx));
680 p + sizeof (bidi_cache_idx) 689 bidi_cache_total_alloc -=
681 + bidi_cache_idx * sizeof (struct bidi_it), 690 sizeof (bidi_cache_idx) + idx * sizeof (struct bidi_it)
682 sizeof (bidi_cache_start_stack)); 691 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp)
683 memcpy (&bidi_cache_sp, 692 + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx);
684 p + sizeof (bidi_cache_idx) 693 }
685 + bidi_cache_idx * sizeof (struct bidi_it) 694 else
686 + sizeof (bidi_cache_start_stack), 695 {
687 sizeof (bidi_cache_sp)); 696 memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx));
688 memcpy (&bidi_cache_start, 697 bidi_cache_ensure_space (bidi_cache_idx);
689 p + sizeof (bidi_cache_idx) 698 memcpy (bidi_cache, p + sizeof (bidi_cache_idx),
690 + bidi_cache_idx * sizeof (struct bidi_it) 699 bidi_cache_idx * sizeof (struct bidi_it));
691 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp), 700 memcpy (bidi_cache_start_stack,
692 sizeof (bidi_cache_start)); 701 p + sizeof (bidi_cache_idx)
693 memcpy (&bidi_cache_last_idx, 702 + bidi_cache_idx * sizeof (struct bidi_it),
694 p + sizeof (bidi_cache_idx) 703 sizeof (bidi_cache_start_stack));
695 + bidi_cache_idx * sizeof (struct bidi_it) 704 memcpy (&bidi_cache_sp,
696 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) 705 p + sizeof (bidi_cache_idx)
697 + sizeof (bidi_cache_start), 706 + bidi_cache_idx * sizeof (struct bidi_it)
698 sizeof (bidi_cache_last_idx)); 707 + sizeof (bidi_cache_start_stack),
708 sizeof (bidi_cache_sp));
709 memcpy (&bidi_cache_start,
710 p + sizeof (bidi_cache_idx)
711 + bidi_cache_idx * sizeof (struct bidi_it)
712 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp),
713 sizeof (bidi_cache_start));
714 memcpy (&bidi_cache_last_idx,
715 p + sizeof (bidi_cache_idx)
716 + bidi_cache_idx * sizeof (struct bidi_it)
717 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp)
718 + sizeof (bidi_cache_start),
719 sizeof (bidi_cache_last_idx));
720 bidi_cache_total_alloc -=
721 sizeof (bidi_cache_idx) + bidi_cache_idx * sizeof (struct bidi_it)
722 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp)
723 + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx);
724 }
699 725
700 xfree (p); 726 xfree (p);
701 } 727 }
diff --git a/src/dispextern.h b/src/dispextern.h
index 2e245479a81..ea4b11baa74 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2978,7 +2978,7 @@ extern int bidi_mirror_char (int);
2978extern void bidi_push_it (struct bidi_it *); 2978extern void bidi_push_it (struct bidi_it *);
2979extern void bidi_pop_it (struct bidi_it *); 2979extern void bidi_pop_it (struct bidi_it *);
2980extern void *bidi_shelve_cache (void); 2980extern void *bidi_shelve_cache (void);
2981extern void bidi_unshelve_cache (void *); 2981extern void bidi_unshelve_cache (void *, int);
2982 2982
2983/* Defined in xdisp.c */ 2983/* Defined in xdisp.c */
2984 2984
diff --git a/src/dispnew.c b/src/dispnew.c
index b2f416701c3..fadfbb26603 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -5282,7 +5282,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
5282 argument is ZV to prevent move_it_in_display_line from matching 5282 argument is ZV to prevent move_it_in_display_line from matching
5283 based on buffer positions. */ 5283 based on buffer positions. */
5284 move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X); 5284 move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X);
5285 bidi_unshelve_cache (itdata); 5285 bidi_unshelve_cache (itdata, 0);
5286 5286
5287 Fset_buffer (old_current_buffer); 5287 Fset_buffer (old_current_buffer);
5288 5288
diff --git a/src/indent.c b/src/indent.c
index aaeaaf591ef..70689311dd5 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -2135,7 +2135,7 @@ whether or not it is currently displayed in some window. */)
2135 } 2135 }
2136 2136
2137 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); 2137 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
2138 bidi_unshelve_cache (itdata); 2138 bidi_unshelve_cache (itdata, 0);
2139 } 2139 }
2140 2140
2141 if (BUFFERP (old_buffer)) 2141 if (BUFFERP (old_buffer))
diff --git a/src/window.c b/src/window.c
index 3f5a743f5c6..8df4a857851 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1379,7 +1379,7 @@ if it isn't already recorded. */)
1379 if (it.current_y < it.last_visible_y) 1379 if (it.current_y < it.last_visible_y)
1380 move_it_past_eol (&it); 1380 move_it_past_eol (&it);
1381 value = make_number (IT_CHARPOS (it)); 1381 value = make_number (IT_CHARPOS (it));
1382 bidi_unshelve_cache (itdata); 1382 bidi_unshelve_cache (itdata, 0);
1383 1383
1384 if (old_buffer) 1384 if (old_buffer)
1385 set_buffer_internal (old_buffer); 1385 set_buffer_internal (old_buffer);
@@ -4273,7 +4273,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4273 } 4273 }
4274 4274
4275 start = it.current.pos; 4275 start = it.current.pos;
4276 bidi_unshelve_cache (itdata); 4276 bidi_unshelve_cache (itdata, 0);
4277 } 4277 }
4278 else if (auto_window_vscroll_p) 4278 else if (auto_window_vscroll_p)
4279 { 4279 {
@@ -4417,7 +4417,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4417 } 4417 }
4418 else 4418 else
4419 { 4419 {
4420 bidi_unshelve_cache (itdata); 4420 bidi_unshelve_cache (itdata, 0);
4421 if (noerror) 4421 if (noerror)
4422 return; 4422 return;
4423 else if (n < 0) /* could happen with empty buffers */ 4423 else if (n < 0) /* could happen with empty buffers */
@@ -4434,7 +4434,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4434 w->vscroll = 0; 4434 w->vscroll = 0;
4435 else 4435 else
4436 { 4436 {
4437 bidi_unshelve_cache (itdata); 4437 bidi_unshelve_cache (itdata, 0);
4438 if (noerror) 4438 if (noerror)
4439 return; 4439 return;
4440 else 4440 else
@@ -4583,7 +4583,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4583 SET_PT_BOTH (charpos, bytepos); 4583 SET_PT_BOTH (charpos, bytepos);
4584 } 4584 }
4585 } 4585 }
4586 bidi_unshelve_cache (itdata); 4586 bidi_unshelve_cache (itdata, 0);
4587} 4587}
4588 4588
4589 4589
@@ -5010,7 +5010,7 @@ displayed_window_lines (struct window *w)
5010 start_display (&it, w, start); 5010 start_display (&it, w, start);
5011 move_it_vertically (&it, height); 5011 move_it_vertically (&it, height);
5012 bottom_y = line_bottom_y (&it); 5012 bottom_y = line_bottom_y (&it);
5013 bidi_unshelve_cache (itdata); 5013 bidi_unshelve_cache (itdata, 0);
5014 5014
5015 /* rms: On a non-window display, 5015 /* rms: On a non-window display,
5016 the value of it.vpos at the bottom of the screen 5016 the value of it.vpos at the bottom of the screen
@@ -5116,7 +5116,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5116 move_it_vertically_backward (&it, window_box_height (w) / 2); 5116 move_it_vertically_backward (&it, window_box_height (w) / 2);
5117 charpos = IT_CHARPOS (it); 5117 charpos = IT_CHARPOS (it);
5118 bytepos = IT_BYTEPOS (it); 5118 bytepos = IT_BYTEPOS (it);
5119 bidi_unshelve_cache (itdata); 5119 bidi_unshelve_cache (itdata, 0);
5120 } 5120 }
5121 else if (iarg < 0) 5121 else if (iarg < 0)
5122 { 5122 {
@@ -5164,7 +5164,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5164 } 5164 }
5165 if (h <= 0) 5165 if (h <= 0)
5166 { 5166 {
5167 bidi_unshelve_cache (itdata); 5167 bidi_unshelve_cache (itdata, 0);
5168 return Qnil; 5168 return Qnil;
5169 } 5169 }
5170 5170
@@ -5187,7 +5187,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5187 charpos = IT_CHARPOS (it); 5187 charpos = IT_CHARPOS (it);
5188 bytepos = IT_BYTEPOS (it); 5188 bytepos = IT_BYTEPOS (it);
5189 5189
5190 bidi_unshelve_cache (itdata); 5190 bidi_unshelve_cache (itdata, 0);
5191 } 5191 }
5192 else 5192 else
5193 { 5193 {
diff --git a/src/xdisp.c b/src/xdisp.c
index 59a6bc3f906..69baea95b9c 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -604,7 +604,7 @@ int current_mode_line_height, current_header_line_height;
604#define SAVE_IT(ITCOPY,ITORIG,CACHE) \ 604#define SAVE_IT(ITCOPY,ITORIG,CACHE) \
605 do { \ 605 do { \
606 if (CACHE) \ 606 if (CACHE) \
607 xfree (CACHE); \ 607 bidi_unshelve_cache (CACHE, 1); \
608 ITCOPY = ITORIG; \ 608 ITCOPY = ITORIG; \
609 CACHE = bidi_shelve_cache(); \ 609 CACHE = bidi_shelve_cache(); \
610 } while (0) 610 } while (0)
@@ -613,7 +613,7 @@ int current_mode_line_height, current_header_line_height;
613 do { \ 613 do { \
614 if (pITORIG != pITCOPY) \ 614 if (pITORIG != pITCOPY) \
615 *(pITORIG) = *(pITCOPY); \ 615 *(pITORIG) = *(pITCOPY); \
616 bidi_unshelve_cache (CACHE); \ 616 bidi_unshelve_cache (CACHE, 0); \
617 CACHE = NULL; \ 617 CACHE = NULL; \
618 } while (0) 618 } while (0)
619 619
@@ -1341,9 +1341,9 @@ pos_visible_p (struct window *w, EMACS_INT charpos, int *x, int *y,
1341 *vpos = it2.vpos; 1341 *vpos = it2.vpos;
1342 } 1342 }
1343 else 1343 else
1344 xfree (it2data); 1344 bidi_unshelve_cache (it2data, 1);
1345 } 1345 }
1346 bidi_unshelve_cache (itdata); 1346 bidi_unshelve_cache (itdata, 0);
1347 1347
1348 if (old_buffer) 1348 if (old_buffer)
1349 set_buffer_internal_1 (old_buffer); 1349 set_buffer_internal_1 (old_buffer);
@@ -2627,7 +2627,7 @@ init_iterator (struct it *it, struct window *w,
2627 it->paragraph_embedding = R2L; 2627 it->paragraph_embedding = R2L;
2628 else 2628 else
2629 it->paragraph_embedding = NEUTRAL_DIR; 2629 it->paragraph_embedding = NEUTRAL_DIR;
2630 bidi_unshelve_cache (NULL); 2630 bidi_unshelve_cache (NULL, 0);
2631 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), 2631 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2632 &it->bidi_it); 2632 &it->bidi_it);
2633 } 2633 }
@@ -5618,7 +5618,7 @@ back_to_previous_visible_line_start (struct it *it)
5618 pos = --IT_CHARPOS (it2); 5618 pos = --IT_CHARPOS (it2);
5619 --IT_BYTEPOS (it2); 5619 --IT_BYTEPOS (it2);
5620 it2.sp = 0; 5620 it2.sp = 0;
5621 bidi_unshelve_cache (NULL); 5621 bidi_unshelve_cache (NULL, 0);
5622 it2.string_from_display_prop_p = 0; 5622 it2.string_from_display_prop_p = 0;
5623 it2.from_disp_prop_p = 0; 5623 it2.from_disp_prop_p = 0;
5624 if (handle_display_prop (&it2) == HANDLED_RETURN 5624 if (handle_display_prop (&it2) == HANDLED_RETURN
@@ -5828,7 +5828,7 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
5828 { 5828 {
5829 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), 5829 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
5830 &it->bidi_it); 5830 &it->bidi_it);
5831 bidi_unshelve_cache (NULL); 5831 bidi_unshelve_cache (NULL, 0);
5832 it->bidi_it.paragraph_dir = NEUTRAL_DIR; 5832 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
5833 it->bidi_it.string.s = NULL; 5833 it->bidi_it.string.s = NULL;
5834 it->bidi_it.string.lstring = Qnil; 5834 it->bidi_it.string.lstring = Qnil;
@@ -8009,13 +8009,13 @@ move_it_in_display_line_to (struct it *it,
8009 positions smaller than TO_CHARPOS, return 8009 positions smaller than TO_CHARPOS, return
8010 MOVE_POS_MATCH_OR_ZV, like the unidirectional display 8010 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
8011 did. */ 8011 did. */
8012 if ((op & MOVE_TO_POS) != 0 8012 if (it->bidi_p && (op & MOVE_TO_POS) != 0
8013 && !saw_smaller_pos 8013 && !saw_smaller_pos
8014 && IT_CHARPOS (*it) > to_charpos) 8014 && IT_CHARPOS (*it) > to_charpos)
8015 { 8015 {
8016 result = MOVE_POS_MATCH_OR_ZV; 8016 if (IT_CHARPOS (ppos_it) < ZV)
8017 if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV)
8018 RESTORE_IT (it, &ppos_it, ppos_data); 8017 RESTORE_IT (it, &ppos_it, ppos_data);
8018 goto buffer_pos_reached;
8019 } 8019 }
8020 else 8020 else
8021 result = MOVE_NEWLINE_OR_CR; 8021 result = MOVE_NEWLINE_OR_CR;
@@ -8054,14 +8054,13 @@ move_it_in_display_line_to (struct it *it,
8054 character positions smaller than TO_CHARPOS, 8054 character positions smaller than TO_CHARPOS,
8055 return MOVE_POS_MATCH_OR_ZV, like the 8055 return MOVE_POS_MATCH_OR_ZV, like the
8056 unidirectional display did. */ 8056 unidirectional display did. */
8057 || ((op & MOVE_TO_POS) != 0 8057 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8058 && !saw_smaller_pos 8058 && !saw_smaller_pos
8059 && IT_CHARPOS (*it) > to_charpos)) 8059 && IT_CHARPOS (*it) > to_charpos))
8060 { 8060 {
8061 result = MOVE_POS_MATCH_OR_ZV; 8061 if (!at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8062 if (it->bidi_p && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8063 RESTORE_IT (it, &ppos_it, ppos_data); 8062 RESTORE_IT (it, &ppos_it, ppos_data);
8064 break; 8063 goto buffer_pos_reached;
8065 } 8064 }
8066 if (ITERATOR_AT_END_OF_LINE_P (it)) 8065 if (ITERATOR_AT_END_OF_LINE_P (it))
8067 { 8066 {
@@ -8069,14 +8068,13 @@ move_it_in_display_line_to (struct it *it,
8069 break; 8068 break;
8070 } 8069 }
8071 } 8070 }
8072 else if ((op & MOVE_TO_POS) != 0 8071 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8073 && !saw_smaller_pos 8072 && !saw_smaller_pos
8074 && IT_CHARPOS (*it) > to_charpos) 8073 && IT_CHARPOS (*it) > to_charpos)
8075 { 8074 {
8076 result = MOVE_POS_MATCH_OR_ZV; 8075 if (IT_CHARPOS (ppos_it) < ZV)
8077 if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV)
8078 RESTORE_IT (it, &ppos_it, ppos_data); 8076 RESTORE_IT (it, &ppos_it, ppos_data);
8079 break; 8077 goto buffer_pos_reached;
8080 } 8078 }
8081 result = MOVE_LINE_TRUNCATED; 8079 result = MOVE_LINE_TRUNCATED;
8082 break; 8080 break;
@@ -8096,13 +8094,13 @@ move_it_in_display_line_to (struct it *it,
8096 done: 8094 done:
8097 8095
8098 if (atpos_data) 8096 if (atpos_data)
8099 xfree (atpos_data); 8097 bidi_unshelve_cache (atpos_data, 1);
8100 if (atx_data) 8098 if (atx_data)
8101 xfree (atx_data); 8099 bidi_unshelve_cache (atx_data, 1);
8102 if (wrap_data) 8100 if (wrap_data)
8103 xfree (wrap_data); 8101 bidi_unshelve_cache (wrap_data, 1);
8104 if (ppos_data) 8102 if (ppos_data)
8105 xfree (ppos_data); 8103 bidi_unshelve_cache (ppos_data, 1);
8106 8104
8107 /* Restore the iterator settings altered at the beginning of this 8105 /* Restore the iterator settings altered at the beginning of this
8108 function. */ 8106 function. */
@@ -8137,7 +8135,7 @@ move_it_in_display_line (struct it *it,
8137 (it, -1, prev_x, MOVE_TO_X); 8135 (it, -1, prev_x, MOVE_TO_X);
8138 } 8136 }
8139 else 8137 else
8140 xfree (save_data); 8138 bidi_unshelve_cache (save_data, 1);
8141 } 8139 }
8142 else 8140 else
8143 move_it_in_display_line_to (it, to_charpos, to_x, op); 8141 move_it_in_display_line_to (it, to_charpos, to_x, op);
@@ -8396,7 +8394,7 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos
8396 } 8394 }
8397 8395
8398 if (backup_data) 8396 if (backup_data)
8399 xfree (backup_data); 8397 bidi_unshelve_cache (backup_data, 1);
8400 8398
8401 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached)); 8399 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
8402} 8400}
@@ -8475,7 +8473,7 @@ move_it_vertically_backward (struct it *it, int dy)
8475 RESTORE_IT (it, it, it2data); 8473 RESTORE_IT (it, it, it2data);
8476 if (nlines > 0) 8474 if (nlines > 0)
8477 move_it_by_lines (it, nlines); 8475 move_it_by_lines (it, nlines);
8478 xfree (it3data); 8476 bidi_unshelve_cache (it3data, 1);
8479 } 8477 }
8480 else 8478 else
8481 { 8479 {
@@ -8671,7 +8669,7 @@ move_it_by_lines (struct it *it, int dvpos)
8671 if (IT_CHARPOS (*it) >= start_charpos) 8669 if (IT_CHARPOS (*it) >= start_charpos)
8672 RESTORE_IT (it, &it2, it2data); 8670 RESTORE_IT (it, &it2, it2data);
8673 else 8671 else
8674 xfree (it2data); 8672 bidi_unshelve_cache (it2data, 1);
8675 } 8673 }
8676 else 8674 else
8677 RESTORE_IT (it, it, it2data); 8675 RESTORE_IT (it, it, it2data);
@@ -18779,6 +18777,9 @@ display_line (struct it *it)
18779 } 18777 }
18780 } 18778 }
18781 18779
18780 if (wrap_data)
18781 bidi_unshelve_cache (wrap_data, 1);
18782
18782 /* If line is not empty and hscrolled, maybe insert truncation glyphs 18783 /* If line is not empty and hscrolled, maybe insert truncation glyphs
18783 at the left window margin. */ 18784 at the left window margin. */
18784 if (it->first_visible_x 18785 if (it->first_visible_x