aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2011-08-05 13:48:37 +0300
committerEli Zaretskii2011-08-05 13:48:37 +0300
commit35928349678bc6ed8f621fe7d4da6a9a3fb3579d (patch)
tree57238a3de3ab2aed53b463a06b866ca2811d878f /src
parent7daee9109e1d69d62528f6b460d101e1ea44f4e1 (diff)
downloademacs-35928349678bc6ed8f621fe7d4da6a9a3fb3579d.tar.gz
emacs-35928349678bc6ed8f621fe7d4da6a9a3fb3579d.zip
Fix bug #9221 with resource allocation under word-wrap.
Add diagnostic facility for monitoring memory allocated for cache shelving. src/xdisp.c (display_line): Release buffer allocated for shelved bidi cache. (Bug#9221) 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 8aa1237f693..481e5e1ce02 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,23 @@
12011-08-05 Eli Zaretskii <eliz@gnu.org>
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
12011-07-24 Eli Zaretskii <eliz@gnu.org> 212011-07-24 Eli Zaretskii <eliz@gnu.org>
2 22
3 * xdisp.c (compute_display_string_pos): Fix logic of caching 23 * xdisp.c (compute_display_string_pos): Fix logic of caching
diff --git a/src/bidi.c b/src/bidi.c
index 77043d9236f..a2ba60a7baf 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -609,12 +609,15 @@ bidi_pop_it (struct bidi_it *bidi_it)
609 bidi_cache_last_idx = -1; 609 bidi_cache_last_idx = -1;
610} 610}
611 611
612ptrdiff_t bidi_cache_total_alloc;
613
612/* Stash away a copy of the cache and its control variables. */ 614/* Stash away a copy of the cache and its control variables. */
613void * 615void *
614bidi_shelve_cache (void) 616bidi_shelve_cache (void)
615{ 617{
616 unsigned char *databuf; 618 unsigned char *databuf;
617 619
620 /* Empty cache. */
618 if (bidi_cache_idx == 0) 621 if (bidi_cache_idx == 0)
619 return NULL; 622 return NULL;
620 623
@@ -623,6 +626,12 @@ bidi_shelve_cache (void)
623 + sizeof (bidi_cache_start_stack) 626 + sizeof (bidi_cache_start_stack)
624 + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start) 627 + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start)
625 + sizeof (bidi_cache_last_idx)); 628 + sizeof (bidi_cache_last_idx));
629 bidi_cache_total_alloc +=
630 sizeof (bidi_cache_idx) + bidi_cache_idx * sizeof (struct bidi_it)
631 + sizeof (bidi_cache_start_stack)
632 + sizeof (bidi_cache_sp) + sizeof (bidi_cache_start)
633 + sizeof (bidi_cache_last_idx);
634
626 memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx)); 635 memcpy (databuf, &bidi_cache_idx, sizeof (bidi_cache_idx));
627 memcpy (databuf + sizeof (bidi_cache_idx), 636 memcpy (databuf + sizeof (bidi_cache_idx),
628 bidi_cache, bidi_cache_idx * sizeof (struct bidi_it)); 637 bidi_cache, bidi_cache_idx * sizeof (struct bidi_it));
@@ -648,7 +657,7 @@ bidi_shelve_cache (void)
648 657
649/* Restore the cache state from a copy stashed away by bidi_shelve_cache. */ 658/* Restore the cache state from a copy stashed away by bidi_shelve_cache. */
650void 659void
651bidi_unshelve_cache (void *databuf) 660bidi_unshelve_cache (void *databuf, int just_free)
652{ 661{
653 unsigned char *p = databuf; 662 unsigned char *p = databuf;
654 663
@@ -661,30 +670,47 @@ bidi_unshelve_cache (void *databuf)
661 } 670 }
662 else 671 else
663 { 672 {
664 memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx)); 673 if (just_free)
665 bidi_cache_ensure_space (bidi_cache_idx); 674 {
666 memcpy (bidi_cache, p + sizeof (bidi_cache_idx), 675 ptrdiff_t idx;
667 bidi_cache_idx * sizeof (struct bidi_it)); 676
668 memcpy (bidi_cache_start_stack, 677 memcpy (&idx, p, sizeof (bidi_cache_idx));
669 p + sizeof (bidi_cache_idx) 678 bidi_cache_total_alloc -=
670 + bidi_cache_idx * sizeof (struct bidi_it), 679 sizeof (bidi_cache_idx) + idx * sizeof (struct bidi_it)
671 sizeof (bidi_cache_start_stack)); 680 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp)
672 memcpy (&bidi_cache_sp, 681 + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx);
673 p + sizeof (bidi_cache_idx) 682 }
674 + bidi_cache_idx * sizeof (struct bidi_it) 683 else
675 + sizeof (bidi_cache_start_stack), 684 {
676 sizeof (bidi_cache_sp)); 685 memcpy (&bidi_cache_idx, p, sizeof (bidi_cache_idx));
677 memcpy (&bidi_cache_start, 686 bidi_cache_ensure_space (bidi_cache_idx);
678 p + sizeof (bidi_cache_idx) 687 memcpy (bidi_cache, p + sizeof (bidi_cache_idx),
679 + bidi_cache_idx * sizeof (struct bidi_it) 688 bidi_cache_idx * sizeof (struct bidi_it));
680 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp), 689 memcpy (bidi_cache_start_stack,
681 sizeof (bidi_cache_start)); 690 p + sizeof (bidi_cache_idx)
682 memcpy (&bidi_cache_last_idx, 691 + bidi_cache_idx * sizeof (struct bidi_it),
683 p + sizeof (bidi_cache_idx) 692 sizeof (bidi_cache_start_stack));
684 + bidi_cache_idx * sizeof (struct bidi_it) 693 memcpy (&bidi_cache_sp,
685 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp) 694 p + sizeof (bidi_cache_idx)
686 + sizeof (bidi_cache_start), 695 + bidi_cache_idx * sizeof (struct bidi_it)
687 sizeof (bidi_cache_last_idx)); 696 + sizeof (bidi_cache_start_stack),
697 sizeof (bidi_cache_sp));
698 memcpy (&bidi_cache_start,
699 p + sizeof (bidi_cache_idx)
700 + bidi_cache_idx * sizeof (struct bidi_it)
701 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp),
702 sizeof (bidi_cache_start));
703 memcpy (&bidi_cache_last_idx,
704 p + sizeof (bidi_cache_idx)
705 + bidi_cache_idx * sizeof (struct bidi_it)
706 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp)
707 + sizeof (bidi_cache_start),
708 sizeof (bidi_cache_last_idx));
709 bidi_cache_total_alloc -=
710 sizeof (bidi_cache_idx) + bidi_cache_idx * sizeof (struct bidi_it)
711 + sizeof (bidi_cache_start_stack) + sizeof (bidi_cache_sp)
712 + sizeof (bidi_cache_start) + sizeof (bidi_cache_last_idx);
713 }
688 714
689 xfree (p); 715 xfree (p);
690 } 716 }
diff --git a/src/dispextern.h b/src/dispextern.h
index 5bb72ff7600..32b4bbfab24 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2975,7 +2975,7 @@ extern int bidi_mirror_char (int);
2975extern void bidi_push_it (struct bidi_it *); 2975extern void bidi_push_it (struct bidi_it *);
2976extern void bidi_pop_it (struct bidi_it *); 2976extern void bidi_pop_it (struct bidi_it *);
2977extern void *bidi_shelve_cache (void); 2977extern void *bidi_shelve_cache (void);
2978extern void bidi_unshelve_cache (void *); 2978extern void bidi_unshelve_cache (void *, int);
2979 2979
2980/* Defined in xdisp.c */ 2980/* Defined in xdisp.c */
2981 2981
diff --git a/src/dispnew.c b/src/dispnew.c
index 69b32a5cd79..64fa5733741 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -5311,7 +5311,7 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p
5311 argument is ZV to prevent move_it_in_display_line from matching 5311 argument is ZV to prevent move_it_in_display_line from matching
5312 based on buffer positions. */ 5312 based on buffer positions. */
5313 move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X); 5313 move_it_in_display_line (&it, ZV, to_x, MOVE_TO_X);
5314 bidi_unshelve_cache (itdata); 5314 bidi_unshelve_cache (itdata, 0);
5315 5315
5316 Fset_buffer (old_current_buffer); 5316 Fset_buffer (old_current_buffer);
5317 5317
diff --git a/src/indent.c b/src/indent.c
index a73284c6657..3f7b3efe3b8 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 094cfcfbda3..d733dea5026 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1190,7 +1190,7 @@ if it isn't already recorded. */)
1190 if (it.current_y < it.last_visible_y) 1190 if (it.current_y < it.last_visible_y)
1191 move_it_past_eol (&it); 1191 move_it_past_eol (&it);
1192 value = make_number (IT_CHARPOS (it)); 1192 value = make_number (IT_CHARPOS (it));
1193 bidi_unshelve_cache (itdata); 1193 bidi_unshelve_cache (itdata, 0);
1194 1194
1195 if (old_buffer) 1195 if (old_buffer)
1196 set_buffer_internal (old_buffer); 1196 set_buffer_internal (old_buffer);
@@ -4771,7 +4771,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4771 } 4771 }
4772 4772
4773 start = it.current.pos; 4773 start = it.current.pos;
4774 bidi_unshelve_cache (itdata); 4774 bidi_unshelve_cache (itdata, 0);
4775 } 4775 }
4776 else if (auto_window_vscroll_p) 4776 else if (auto_window_vscroll_p)
4777 { 4777 {
@@ -4915,7 +4915,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4915 } 4915 }
4916 else 4916 else
4917 { 4917 {
4918 bidi_unshelve_cache (itdata); 4918 bidi_unshelve_cache (itdata, 0);
4919 if (noerror) 4919 if (noerror)
4920 return; 4920 return;
4921 else if (n < 0) /* could happen with empty buffers */ 4921 else if (n < 0) /* could happen with empty buffers */
@@ -4932,7 +4932,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
4932 w->vscroll = 0; 4932 w->vscroll = 0;
4933 else 4933 else
4934 { 4934 {
4935 bidi_unshelve_cache (itdata); 4935 bidi_unshelve_cache (itdata, 0);
4936 if (noerror) 4936 if (noerror)
4937 return; 4937 return;
4938 else 4938 else
@@ -5081,7 +5081,7 @@ window_scroll_pixel_based (Lisp_Object window, int n, int whole, int noerror)
5081 SET_PT_BOTH (charpos, bytepos); 5081 SET_PT_BOTH (charpos, bytepos);
5082 } 5082 }
5083 } 5083 }
5084 bidi_unshelve_cache (itdata); 5084 bidi_unshelve_cache (itdata, 0);
5085} 5085}
5086 5086
5087 5087
@@ -5508,7 +5508,7 @@ displayed_window_lines (struct window *w)
5508 start_display (&it, w, start); 5508 start_display (&it, w, start);
5509 move_it_vertically (&it, height); 5509 move_it_vertically (&it, height);
5510 bottom_y = line_bottom_y (&it); 5510 bottom_y = line_bottom_y (&it);
5511 bidi_unshelve_cache (itdata); 5511 bidi_unshelve_cache (itdata, 0);
5512 5512
5513 /* rms: On a non-window display, 5513 /* rms: On a non-window display,
5514 the value of it.vpos at the bottom of the screen 5514 the value of it.vpos at the bottom of the screen
@@ -5614,7 +5614,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5614 move_it_vertically_backward (&it, window_box_height (w) / 2); 5614 move_it_vertically_backward (&it, window_box_height (w) / 2);
5615 charpos = IT_CHARPOS (it); 5615 charpos = IT_CHARPOS (it);
5616 bytepos = IT_BYTEPOS (it); 5616 bytepos = IT_BYTEPOS (it);
5617 bidi_unshelve_cache (itdata); 5617 bidi_unshelve_cache (itdata, 0);
5618 } 5618 }
5619 else if (iarg < 0) 5619 else if (iarg < 0)
5620 { 5620 {
@@ -5662,7 +5662,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5662 } 5662 }
5663 if (h <= 0) 5663 if (h <= 0)
5664 { 5664 {
5665 bidi_unshelve_cache (itdata); 5665 bidi_unshelve_cache (itdata, 0);
5666 return Qnil; 5666 return Qnil;
5667 } 5667 }
5668 5668
@@ -5685,7 +5685,7 @@ and redisplay normally--don't erase and redraw the frame. */)
5685 charpos = IT_CHARPOS (it); 5685 charpos = IT_CHARPOS (it);
5686 bytepos = IT_BYTEPOS (it); 5686 bytepos = IT_BYTEPOS (it);
5687 5687
5688 bidi_unshelve_cache (itdata); 5688 bidi_unshelve_cache (itdata, 0);
5689 } 5689 }
5690 else 5690 else
5691 { 5691 {
diff --git a/src/xdisp.c b/src/xdisp.c
index 5f9e80cd11e..77bd4e5ee9a 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);
@@ -2629,7 +2629,7 @@ init_iterator (struct it *it, struct window *w,
2629 it->paragraph_embedding = R2L; 2629 it->paragraph_embedding = R2L;
2630 else 2630 else
2631 it->paragraph_embedding = NEUTRAL_DIR; 2631 it->paragraph_embedding = NEUTRAL_DIR;
2632 bidi_unshelve_cache (NULL); 2632 bidi_unshelve_cache (NULL, 0);
2633 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), 2633 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
2634 &it->bidi_it); 2634 &it->bidi_it);
2635 } 2635 }
@@ -5635,7 +5635,7 @@ back_to_previous_visible_line_start (struct it *it)
5635 pos = --IT_CHARPOS (it2); 5635 pos = --IT_CHARPOS (it2);
5636 --IT_BYTEPOS (it2); 5636 --IT_BYTEPOS (it2);
5637 it2.sp = 0; 5637 it2.sp = 0;
5638 bidi_unshelve_cache (NULL); 5638 bidi_unshelve_cache (NULL, 0);
5639 it2.string_from_display_prop_p = 0; 5639 it2.string_from_display_prop_p = 0;
5640 it2.from_disp_prop_p = 0; 5640 it2.from_disp_prop_p = 0;
5641 if (handle_display_prop (&it2) == HANDLED_RETURN 5641 if (handle_display_prop (&it2) == HANDLED_RETURN
@@ -5827,7 +5827,7 @@ reseat_1 (struct it *it, struct text_pos pos, int set_stop_p)
5827 { 5827 {
5828 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f), 5828 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
5829 &it->bidi_it); 5829 &it->bidi_it);
5830 bidi_unshelve_cache (NULL); 5830 bidi_unshelve_cache (NULL, 0);
5831 it->bidi_it.paragraph_dir = NEUTRAL_DIR; 5831 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
5832 it->bidi_it.string.s = NULL; 5832 it->bidi_it.string.s = NULL;
5833 it->bidi_it.string.lstring = Qnil; 5833 it->bidi_it.string.lstring = Qnil;
@@ -7995,13 +7995,13 @@ move_it_in_display_line_to (struct it *it,
7995 positions smaller than TO_CHARPOS, return 7995 positions smaller than TO_CHARPOS, return
7996 MOVE_POS_MATCH_OR_ZV, like the unidirectional display 7996 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
7997 did. */ 7997 did. */
7998 if ((op & MOVE_TO_POS) != 0 7998 if (it->bidi_p && (op & MOVE_TO_POS) != 0
7999 && !saw_smaller_pos 7999 && !saw_smaller_pos
8000 && IT_CHARPOS (*it) > to_charpos) 8000 && IT_CHARPOS (*it) > to_charpos)
8001 { 8001 {
8002 result = MOVE_POS_MATCH_OR_ZV; 8002 if (IT_CHARPOS (ppos_it) < ZV)
8003 if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV)
8004 RESTORE_IT (it, &ppos_it, ppos_data); 8003 RESTORE_IT (it, &ppos_it, ppos_data);
8004 goto buffer_pos_reached;
8005 } 8005 }
8006 else 8006 else
8007 result = MOVE_NEWLINE_OR_CR; 8007 result = MOVE_NEWLINE_OR_CR;
@@ -8040,14 +8040,13 @@ move_it_in_display_line_to (struct it *it,
8040 character positions smaller than TO_CHARPOS, 8040 character positions smaller than TO_CHARPOS,
8041 return MOVE_POS_MATCH_OR_ZV, like the 8041 return MOVE_POS_MATCH_OR_ZV, like the
8042 unidirectional display did. */ 8042 unidirectional display did. */
8043 || ((op & MOVE_TO_POS) != 0 8043 || (it->bidi_p && (op & MOVE_TO_POS) != 0
8044 && !saw_smaller_pos 8044 && !saw_smaller_pos
8045 && IT_CHARPOS (*it) > to_charpos)) 8045 && IT_CHARPOS (*it) > to_charpos))
8046 { 8046 {
8047 result = MOVE_POS_MATCH_OR_ZV; 8047 if (!at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8048 if (it->bidi_p && !at_eob_p && IT_CHARPOS (ppos_it) < ZV)
8049 RESTORE_IT (it, &ppos_it, ppos_data); 8048 RESTORE_IT (it, &ppos_it, ppos_data);
8050 break; 8049 goto buffer_pos_reached;
8051 } 8050 }
8052 if (ITERATOR_AT_END_OF_LINE_P (it)) 8051 if (ITERATOR_AT_END_OF_LINE_P (it))
8053 { 8052 {
@@ -8055,14 +8054,13 @@ move_it_in_display_line_to (struct it *it,
8055 break; 8054 break;
8056 } 8055 }
8057 } 8056 }
8058 else if ((op & MOVE_TO_POS) != 0 8057 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
8059 && !saw_smaller_pos 8058 && !saw_smaller_pos
8060 && IT_CHARPOS (*it) > to_charpos) 8059 && IT_CHARPOS (*it) > to_charpos)
8061 { 8060 {
8062 result = MOVE_POS_MATCH_OR_ZV; 8061 if (IT_CHARPOS (ppos_it) < ZV)
8063 if (it->bidi_p && IT_CHARPOS (ppos_it) < ZV)
8064 RESTORE_IT (it, &ppos_it, ppos_data); 8062 RESTORE_IT (it, &ppos_it, ppos_data);
8065 break; 8063 goto buffer_pos_reached;
8066 } 8064 }
8067 result = MOVE_LINE_TRUNCATED; 8065 result = MOVE_LINE_TRUNCATED;
8068 break; 8066 break;
@@ -8082,13 +8080,13 @@ move_it_in_display_line_to (struct it *it,
8082 done: 8080 done:
8083 8081
8084 if (atpos_data) 8082 if (atpos_data)
8085 xfree (atpos_data); 8083 bidi_unshelve_cache (atpos_data, 1);
8086 if (atx_data) 8084 if (atx_data)
8087 xfree (atx_data); 8085 bidi_unshelve_cache (atx_data, 1);
8088 if (wrap_data) 8086 if (wrap_data)
8089 xfree (wrap_data); 8087 bidi_unshelve_cache (wrap_data, 1);
8090 if (ppos_data) 8088 if (ppos_data)
8091 xfree (ppos_data); 8089 bidi_unshelve_cache (ppos_data, 1);
8092 8090
8093 /* Restore the iterator settings altered at the beginning of this 8091 /* Restore the iterator settings altered at the beginning of this
8094 function. */ 8092 function. */
@@ -8123,7 +8121,7 @@ move_it_in_display_line (struct it *it,
8123 (it, -1, prev_x, MOVE_TO_X); 8121 (it, -1, prev_x, MOVE_TO_X);
8124 } 8122 }
8125 else 8123 else
8126 xfree (save_data); 8124 bidi_unshelve_cache (save_data, 1);
8127 } 8125 }
8128 else 8126 else
8129 move_it_in_display_line_to (it, to_charpos, to_x, op); 8127 move_it_in_display_line_to (it, to_charpos, to_x, op);
@@ -8382,7 +8380,7 @@ move_it_to (struct it *it, EMACS_INT to_charpos, int to_x, int to_y, int to_vpos
8382 } 8380 }
8383 8381
8384 if (backup_data) 8382 if (backup_data)
8385 xfree (backup_data); 8383 bidi_unshelve_cache (backup_data, 1);
8386 8384
8387 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached)); 8385 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
8388} 8386}
@@ -8461,7 +8459,7 @@ move_it_vertically_backward (struct it *it, int dy)
8461 RESTORE_IT (it, it, it2data); 8459 RESTORE_IT (it, it, it2data);
8462 if (nlines > 0) 8460 if (nlines > 0)
8463 move_it_by_lines (it, nlines); 8461 move_it_by_lines (it, nlines);
8464 xfree (it3data); 8462 bidi_unshelve_cache (it3data, 1);
8465 } 8463 }
8466 else 8464 else
8467 { 8465 {
@@ -8657,7 +8655,7 @@ move_it_by_lines (struct it *it, int dvpos)
8657 if (IT_CHARPOS (*it) >= start_charpos) 8655 if (IT_CHARPOS (*it) >= start_charpos)
8658 RESTORE_IT (it, &it2, it2data); 8656 RESTORE_IT (it, &it2, it2data);
8659 else 8657 else
8660 xfree (it2data); 8658 bidi_unshelve_cache (it2data, 1);
8661 } 8659 }
8662 else 8660 else
8663 RESTORE_IT (it, it, it2data); 8661 RESTORE_IT (it, it, it2data);
@@ -18764,6 +18762,9 @@ display_line (struct it *it)
18764 } 18762 }
18765 } 18763 }
18766 18764
18765 if (wrap_data)
18766 bidi_unshelve_cache (wrap_data, 1);
18767
18767 /* If line is not empty and hscrolled, maybe insert truncation glyphs 18768 /* If line is not empty and hscrolled, maybe insert truncation glyphs
18768 at the left window margin. */ 18769 at the left window margin. */
18769 if (it->first_visible_x 18770 if (it->first_visible_x