diff options
| author | Andrea Corallo | 2020-05-30 11:52:27 +0100 |
|---|---|---|
| committer | Andrea Corallo | 2020-05-30 11:52:27 +0100 |
| commit | eeebbd5fcbdf2827689311b3751437670bfc2e22 (patch) | |
| tree | b0b6c946b5fc2743006a476d2df29025f2c57cc7 /src | |
| parent | 15c121ee0b5cbe005548eeba09dd54b145b2e258 (diff) | |
| parent | f42db4b6e1598c12924cce4bbe4d67e6d86b7963 (diff) | |
| download | emacs-eeebbd5fcbdf2827689311b3751437670bfc2e22.tar.gz emacs-eeebbd5fcbdf2827689311b3751437670bfc2e22.zip | |
Merge remote-tracking branch 'savannah/master' into HEAD
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 94 | ||||
| -rw-r--r-- | src/cmds.c | 4 | ||||
| -rw-r--r-- | src/coding.c | 4 | ||||
| -rw-r--r-- | src/lisp.h | 13 | ||||
| -rw-r--r-- | src/lread.c | 4 | ||||
| -rw-r--r-- | src/pdumper.c | 2 | ||||
| -rw-r--r-- | src/thread.c | 9 | ||||
| -rw-r--r-- | src/xdisp.c | 18 |
8 files changed, 109 insertions, 39 deletions
diff --git a/src/alloc.c b/src/alloc.c index b892022125e..dc92d67f163 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -104,6 +104,46 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 104 | #include "w32heap.h" /* for sbrk */ | 104 | #include "w32heap.h" /* for sbrk */ |
| 105 | #endif | 105 | #endif |
| 106 | 106 | ||
| 107 | /* A type with alignment at least as large as any object that Emacs | ||
| 108 | allocates. This is not max_align_t because some platforms (e.g., | ||
| 109 | mingw) have buggy malloc implementations that do not align for | ||
| 110 | max_align_t. This union contains types of all GCALIGNED_STRUCT | ||
| 111 | components visible here. */ | ||
| 112 | union emacs_align_type | ||
| 113 | { | ||
| 114 | struct frame frame; | ||
| 115 | struct Lisp_Bignum Lisp_Bignum; | ||
| 116 | struct Lisp_Bool_Vector Lisp_Bool_Vector; | ||
| 117 | struct Lisp_Char_Table Lisp_Char_Table; | ||
| 118 | struct Lisp_CondVar Lisp_CondVar; | ||
| 119 | struct Lisp_Finalizer Lisp_Finalizer; | ||
| 120 | struct Lisp_Float Lisp_Float; | ||
| 121 | struct Lisp_Hash_Table Lisp_Hash_Table; | ||
| 122 | struct Lisp_Marker Lisp_Marker; | ||
| 123 | struct Lisp_Misc_Ptr Lisp_Misc_Ptr; | ||
| 124 | struct Lisp_Mutex Lisp_Mutex; | ||
| 125 | struct Lisp_Overlay Lisp_Overlay; | ||
| 126 | struct Lisp_Sub_Char_Table Lisp_Sub_Char_Table; | ||
| 127 | struct Lisp_Subr Lisp_Subr; | ||
| 128 | struct Lisp_User_Ptr Lisp_User_Ptr; | ||
| 129 | struct Lisp_Vector Lisp_Vector; | ||
| 130 | struct terminal terminal; | ||
| 131 | struct thread_state thread_state; | ||
| 132 | struct window window; | ||
| 133 | |||
| 134 | /* Omit the following since they would require including process.h | ||
| 135 | etc. In practice their alignments never exceed that of the | ||
| 136 | structs already listed. */ | ||
| 137 | #if 0 | ||
| 138 | struct Lisp_Module_Function Lisp_Module_Function; | ||
| 139 | struct Lisp_Process Lisp_Process; | ||
| 140 | struct save_window_data save_window_data; | ||
| 141 | struct scroll_bar scroll_bar; | ||
| 142 | struct xwidget_view xwidget_view; | ||
| 143 | struct xwidget xwidget; | ||
| 144 | #endif | ||
| 145 | }; | ||
| 146 | |||
| 107 | /* MALLOC_SIZE_NEAR (N) is a good number to pass to malloc when | 147 | /* MALLOC_SIZE_NEAR (N) is a good number to pass to malloc when |
| 108 | allocating a block of memory with size close to N bytes. | 148 | allocating a block of memory with size close to N bytes. |
| 109 | For best results N should be a power of 2. | 149 | For best results N should be a power of 2. |
| @@ -112,9 +152,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 112 | adds sizeof (size_t) to SIZE for internal overhead, and then rounds | 152 | adds sizeof (size_t) to SIZE for internal overhead, and then rounds |
| 113 | up to a multiple of MALLOC_ALIGNMENT. Emacs can improve | 153 | up to a multiple of MALLOC_ALIGNMENT. Emacs can improve |
| 114 | performance a bit on GNU platforms by arranging for the resulting | 154 | performance a bit on GNU platforms by arranging for the resulting |
| 115 | size to be a power of two. This heuristic is good for glibc 2.0 | 155 | size to be a power of two. This heuristic is good for glibc 2.26 |
| 116 | (1997) through at least glibc 2.31 (2020), and does not affect | 156 | (2017) and later, and does not affect correctness on other |
| 117 | correctness on other platforms. */ | 157 | platforms. */ |
| 118 | 158 | ||
| 119 | #define MALLOC_SIZE_NEAR(n) \ | 159 | #define MALLOC_SIZE_NEAR(n) \ |
| 120 | (ROUNDUP (max (n, sizeof (size_t)), MALLOC_ALIGNMENT) - sizeof (size_t)) | 160 | (ROUNDUP (max (n, sizeof (size_t)), MALLOC_ALIGNMENT) - sizeof (size_t)) |
| @@ -655,25 +695,19 @@ buffer_memory_full (ptrdiff_t nbytes) | |||
| 655 | #define COMMON_MULTIPLE(a, b) \ | 695 | #define COMMON_MULTIPLE(a, b) \ |
| 656 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) | 696 | ((a) % (b) == 0 ? (a) : (b) % (a) == 0 ? (b) : (a) * (b)) |
| 657 | 697 | ||
| 658 | /* LISP_ALIGNMENT is the alignment of Lisp objects. It must be at | 698 | /* Alignment needed for memory blocks that are allocated via malloc |
| 659 | least GCALIGNMENT so that pointers can be tagged. It also must be | 699 | and that contain Lisp objects. On typical hosts malloc already |
| 660 | at least as strict as the alignment of all the C types used to | 700 | aligns sufficiently, but extra work is needed on oddball hosts |
| 661 | implement Lisp objects; since pseudovectors can contain any C type, | 701 | where Emacs would crash if malloc returned a non-GCALIGNED pointer. */ |
| 662 | this is max_align_t. On recent GNU/Linux x86 and x86-64 this can | 702 | enum { LISP_ALIGNMENT = alignof (union { union emacs_align_type x; |
| 663 | often waste up to 8 bytes, since alignof (max_align_t) is 16 but | ||
| 664 | typical vectors need only an alignment of 8. Although shrinking | ||
| 665 | the alignment to 8 would save memory, it cost a 20% hit to Emacs | ||
| 666 | CPU performance on Fedora 28 x86-64 when compiled with gcc -m32. */ | ||
| 667 | enum { LISP_ALIGNMENT = alignof (union { max_align_t x; | ||
| 668 | GCALIGNED_UNION_MEMBER }) }; | 703 | GCALIGNED_UNION_MEMBER }) }; |
| 669 | verify (LISP_ALIGNMENT % GCALIGNMENT == 0); | 704 | verify (LISP_ALIGNMENT % GCALIGNMENT == 0); |
| 670 | 705 | ||
| 671 | /* True if malloc (N) is known to return storage suitably aligned for | 706 | /* True if malloc (N) is known to return storage suitably aligned for |
| 672 | Lisp objects whenever N is a multiple of LISP_ALIGNMENT. In | 707 | Lisp objects whenever N is a multiple of LISP_ALIGNMENT. In |
| 673 | practice this is true whenever alignof (max_align_t) is also a | 708 | practice this is true whenever alignof (max_align_t) is also a |
| 674 | multiple of LISP_ALIGNMENT. This works even for x86, where some | 709 | multiple of LISP_ALIGNMENT. This works even for buggy platforms |
| 675 | platform combinations (e.g., GCC 7 and later, glibc 2.25 and | 710 | like MinGW circa 2020, where alignof (max_align_t) is 16 even though |
| 676 | earlier) have bugs where alignof (max_align_t) is 16 even though | ||
| 677 | the malloc alignment is only 8, and where Emacs still works because | 711 | the malloc alignment is only 8, and where Emacs still works because |
| 678 | it never does anything that requires an alignment of 16. */ | 712 | it never does anything that requires an alignment of 16. */ |
| 679 | enum { MALLOC_IS_LISP_ALIGNED = alignof (max_align_t) % LISP_ALIGNMENT == 0 }; | 713 | enum { MALLOC_IS_LISP_ALIGNED = alignof (max_align_t) % LISP_ALIGNMENT == 0 }; |
| @@ -4660,16 +4694,33 @@ mark_maybe_objects (Lisp_Object const *array, ptrdiff_t nelts) | |||
| 4660 | mark_maybe_object (*array); | 4694 | mark_maybe_object (*array); |
| 4661 | } | 4695 | } |
| 4662 | 4696 | ||
| 4697 | /* A lower bound on the alignment of Lisp objects that need marking. | ||
| 4698 | Although 1 is safe, higher values speed up mark_maybe_pointer. | ||
| 4699 | If USE_LSB_TAG, this value is typically GCALIGNMENT; otherwise, | ||
| 4700 | it's determined by the natural alignment of Lisp structs. | ||
| 4701 | All vectorlike objects have alignment at least that of union | ||
| 4702 | vectorlike_header and it's unlikely they all have alignment greater, | ||
| 4703 | so use the union as a safe and likely-accurate standin for | ||
| 4704 | vectorlike objects. */ | ||
| 4705 | |||
| 4706 | enum { GC_OBJECT_ALIGNMENT_MINIMUM | ||
| 4707 | = max (GCALIGNMENT, | ||
| 4708 | min (alignof (union vectorlike_header), | ||
| 4709 | min (min (alignof (struct Lisp_Cons), | ||
| 4710 | alignof (struct Lisp_Float)), | ||
| 4711 | min (alignof (struct Lisp_String), | ||
| 4712 | alignof (struct Lisp_Symbol))))) }; | ||
| 4713 | |||
| 4663 | /* Return true if P might point to Lisp data that can be garbage | 4714 | /* Return true if P might point to Lisp data that can be garbage |
| 4664 | collected, and false otherwise (i.e., false if it is easy to see | 4715 | collected, and false otherwise (i.e., false if it is easy to see |
| 4665 | that P cannot point to Lisp data that can be garbage collected). | 4716 | that P cannot point to Lisp data that can be garbage collected). |
| 4666 | Symbols are implemented via offsets not pointers, but the offsets | 4717 | Symbols are implemented via offsets not pointers, but the offsets |
| 4667 | are also multiples of LISP_ALIGNMENT. */ | 4718 | are also multiples of GC_OBJECT_ALIGNMENT_MINIMUM. */ |
| 4668 | 4719 | ||
| 4669 | static bool | 4720 | static bool |
| 4670 | maybe_lisp_pointer (void *p) | 4721 | maybe_lisp_pointer (void *p) |
| 4671 | { | 4722 | { |
| 4672 | return (uintptr_t) p % LISP_ALIGNMENT == 0; | 4723 | return (uintptr_t) p % GC_OBJECT_ALIGNMENT_MINIMUM == 0; |
| 4673 | } | 4724 | } |
| 4674 | 4725 | ||
| 4675 | /* If P points to Lisp data, mark that as live if it isn't already | 4726 | /* If P points to Lisp data, mark that as live if it isn't already |
| @@ -4892,9 +4943,10 @@ test_setjmp (void) | |||
| 4892 | as a stack scan limit. */ | 4943 | as a stack scan limit. */ |
| 4893 | typedef union | 4944 | typedef union |
| 4894 | { | 4945 | { |
| 4895 | /* Align the stack top properly. Even if !HAVE___BUILTIN_UNWIND_INIT, | 4946 | /* Make sure stack_top and m_stack_bottom are properly aligned as GC |
| 4896 | jmp_buf may not be aligned enough on darwin-ppc64. */ | 4947 | expects. */ |
| 4897 | max_align_t o; | 4948 | Lisp_Object o; |
| 4949 | void *p; | ||
| 4898 | #ifndef HAVE___BUILTIN_UNWIND_INIT | 4950 | #ifndef HAVE___BUILTIN_UNWIND_INIT |
| 4899 | sys_jmp_buf j; | 4951 | sys_jmp_buf j; |
| 4900 | char c; | 4952 | char c; |
diff --git a/src/cmds.c b/src/cmds.c index 9f96f210b9f..90526612b7a 100644 --- a/src/cmds.c +++ b/src/cmds.c | |||
| @@ -194,7 +194,7 @@ to t. */) | |||
| 194 | SET_PT (newpos); | 194 | SET_PT (newpos); |
| 195 | 195 | ||
| 196 | if (PT > newpos | 196 | if (PT > newpos |
| 197 | && FETCH_CHAR (PT - 1) == '\n') | 197 | && FETCH_BYTE (PT_BYTE - 1) == '\n') |
| 198 | { | 198 | { |
| 199 | /* If we skipped over a newline that follows | 199 | /* If we skipped over a newline that follows |
| 200 | an invisible intangible run, | 200 | an invisible intangible run, |
| @@ -205,7 +205,7 @@ to t. */) | |||
| 205 | break; | 205 | break; |
| 206 | } | 206 | } |
| 207 | else if (PT > newpos && PT < ZV | 207 | else if (PT > newpos && PT < ZV |
| 208 | && FETCH_CHAR (PT) != '\n') | 208 | && FETCH_BYTE (PT_BYTE) != '\n') |
| 209 | /* If we skipped something intangible | 209 | /* If we skipped something intangible |
| 210 | and now we're not really at eol, | 210 | and now we're not really at eol, |
| 211 | keep going. */ | 211 | keep going. */ |
diff --git a/src/coding.c b/src/coding.c index 34f36d5a86a..071124b4ef1 100644 --- a/src/coding.c +++ b/src/coding.c | |||
| @@ -10395,7 +10395,7 @@ representation of the decoded text. | |||
| 10395 | 10395 | ||
| 10396 | This function sets `last-coding-system-used' to the precise coding system | 10396 | This function sets `last-coding-system-used' to the precise coding system |
| 10397 | used (which may be different from CODING-SYSTEM if CODING-SYSTEM is | 10397 | used (which may be different from CODING-SYSTEM if CODING-SYSTEM is |
| 10398 | not fully specified.) */) | 10398 | not fully specified.) The function does not change the match data. */) |
| 10399 | (Lisp_Object string, Lisp_Object coding_system, Lisp_Object nocopy, Lisp_Object buffer) | 10399 | (Lisp_Object string, Lisp_Object coding_system, Lisp_Object nocopy, Lisp_Object buffer) |
| 10400 | { | 10400 | { |
| 10401 | return code_convert_string (string, coding_system, buffer, | 10401 | return code_convert_string (string, coding_system, buffer, |
| @@ -10415,7 +10415,7 @@ case, the return value is the length of the encoded text. | |||
| 10415 | 10415 | ||
| 10416 | This function sets `last-coding-system-used' to the precise coding system | 10416 | This function sets `last-coding-system-used' to the precise coding system |
| 10417 | used (which may be different from CODING-SYSTEM if CODING-SYSTEM is | 10417 | used (which may be different from CODING-SYSTEM if CODING-SYSTEM is |
| 10418 | not fully specified.) */) | 10418 | not fully specified.) The function does not change the match data. */) |
| 10419 | (Lisp_Object string, Lisp_Object coding_system, Lisp_Object nocopy, Lisp_Object buffer) | 10419 | (Lisp_Object string, Lisp_Object coding_system, Lisp_Object nocopy, Lisp_Object buffer) |
| 10420 | { | 10420 | { |
| 10421 | return code_convert_string (string, coding_system, buffer, | 10421 | return code_convert_string (string, coding_system, buffer, |
diff --git a/src/lisp.h b/src/lisp.h index 52242791aa5..d39300e5598 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -251,12 +251,6 @@ DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK) | |||
| 251 | # define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX) | 251 | # define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX) |
| 252 | DEFINE_GDB_SYMBOL_END (VALMASK) | 252 | DEFINE_GDB_SYMBOL_END (VALMASK) |
| 253 | 253 | ||
| 254 | #if !USE_LSB_TAG && !defined WIDE_EMACS_INT | ||
| 255 | # error "USE_LSB_TAG not supported on this platform; please report this." \ | ||
| 256 | "Try 'configure --with-wide-int' to work around the problem." | ||
| 257 | error !; | ||
| 258 | #endif | ||
| 259 | |||
| 260 | /* Minimum alignment requirement for Lisp objects, imposed by the | 254 | /* Minimum alignment requirement for Lisp objects, imposed by the |
| 261 | internal representation of tagged pointers. It is 2**GCTYPEBITS if | 255 | internal representation of tagged pointers. It is 2**GCTYPEBITS if |
| 262 | USE_LSB_TAG, 1 otherwise. It must be a literal integer constant, | 256 | USE_LSB_TAG, 1 otherwise. It must be a literal integer constant, |
| @@ -277,7 +271,8 @@ error !; | |||
| 277 | allocation in a containing union that has GCALIGNED_UNION_MEMBER) | 271 | allocation in a containing union that has GCALIGNED_UNION_MEMBER) |
| 278 | and does not contain a GC-aligned struct or union, putting | 272 | and does not contain a GC-aligned struct or union, putting |
| 279 | GCALIGNED_STRUCT after its closing '}' can help the compiler | 273 | GCALIGNED_STRUCT after its closing '}' can help the compiler |
| 280 | generate better code. | 274 | generate better code. Also, such structs should be added to the |
| 275 | emacs_align_type union in alloc.c. | ||
| 281 | 276 | ||
| 282 | Although these macros are reasonably portable, they are not | 277 | Although these macros are reasonably portable, they are not |
| 283 | guaranteed on non-GCC platforms, as C11 does not require support | 278 | guaranteed on non-GCC platforms, as C11 does not require support |
| @@ -2809,8 +2804,10 @@ struct Lisp_Float | |||
| 2809 | { | 2804 | { |
| 2810 | double data; | 2805 | double data; |
| 2811 | struct Lisp_Float *chain; | 2806 | struct Lisp_Float *chain; |
| 2807 | GCALIGNED_UNION_MEMBER | ||
| 2812 | } u; | 2808 | } u; |
| 2813 | } GCALIGNED_STRUCT; | 2809 | }; |
| 2810 | verify (GCALIGNED (struct Lisp_Float)); | ||
| 2814 | 2811 | ||
| 2815 | INLINE bool | 2812 | INLINE bool |
| 2816 | (FLOATP) (Lisp_Object x) | 2813 | (FLOATP) (Lisp_Object x) |
diff --git a/src/lread.c b/src/lread.c index 46725d9b0ff..9f849eda423 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -3908,6 +3908,10 @@ read_vector (Lisp_Object readcharfun, bool bytecodeflag) | |||
| 3908 | ptrdiff_t size = list_length (tem); | 3908 | ptrdiff_t size = list_length (tem); |
| 3909 | Lisp_Object vector = make_nil_vector (size); | 3909 | Lisp_Object vector = make_nil_vector (size); |
| 3910 | 3910 | ||
| 3911 | /* Avoid accessing past the end of a vector if the vector is too | ||
| 3912 | small to be valid for bytecode. */ | ||
| 3913 | bytecodeflag &= COMPILED_STACK_DEPTH < size; | ||
| 3914 | |||
| 3911 | Lisp_Object *ptr = XVECTOR (vector)->contents; | 3915 | Lisp_Object *ptr = XVECTOR (vector)->contents; |
| 3912 | for (ptrdiff_t i = 0; i < size; i++) | 3916 | for (ptrdiff_t i = 0; i < size; i++) |
| 3913 | { | 3917 | { |
diff --git a/src/pdumper.c b/src/pdumper.c index 19dbacca896..29e3560ee5a 100644 --- a/src/pdumper.c +++ b/src/pdumper.c | |||
| @@ -2620,7 +2620,7 @@ dump_vectorlike_generic (struct dump_context *ctx, | |||
| 2620 | Lisp_Object out; | 2620 | Lisp_Object out; |
| 2621 | const Lisp_Object *vslot = &v->contents[i]; | 2621 | const Lisp_Object *vslot = &v->contents[i]; |
| 2622 | /* In the wide case, we're always misaligned. */ | 2622 | /* In the wide case, we're always misaligned. */ |
| 2623 | #ifndef WIDE_EMACS_INT | 2623 | #if INTPTR_MAX == EMACS_INT_MAX |
| 2624 | eassert (ctx->offset % sizeof (out) == 0); | 2624 | eassert (ctx->offset % sizeof (out) == 0); |
| 2625 | #endif | 2625 | #endif |
| 2626 | dump_object_start (ctx, &out, sizeof (out)); | 2626 | dump_object_start (ctx, &out, sizeof (out)); |
diff --git a/src/thread.c b/src/thread.c index df1a7053826..b638dd77f8b 100644 --- a/src/thread.c +++ b/src/thread.c | |||
| @@ -717,12 +717,17 @@ run_thread (void *state) | |||
| 717 | { | 717 | { |
| 718 | /* Make sure stack_top and m_stack_bottom are properly aligned as GC | 718 | /* Make sure stack_top and m_stack_bottom are properly aligned as GC |
| 719 | expects. */ | 719 | expects. */ |
| 720 | max_align_t stack_pos; | 720 | union |
| 721 | { | ||
| 722 | Lisp_Object o; | ||
| 723 | void *p; | ||
| 724 | char c; | ||
| 725 | } stack_pos; | ||
| 721 | 726 | ||
| 722 | struct thread_state *self = state; | 727 | struct thread_state *self = state; |
| 723 | struct thread_state **iter; | 728 | struct thread_state **iter; |
| 724 | 729 | ||
| 725 | self->m_stack_bottom = self->stack_top = (char *) &stack_pos; | 730 | self->m_stack_bottom = self->stack_top = &stack_pos.c; |
| 726 | self->thread_id = sys_thread_self (); | 731 | self->thread_id = sys_thread_self (); |
| 727 | 732 | ||
| 728 | if (self->thread_name) | 733 | if (self->thread_name) |
diff --git a/src/xdisp.c b/src/xdisp.c index cf15f579b58..db0ec683159 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -8290,8 +8290,8 @@ get_visually_first_element (struct it *it) | |||
| 8290 | } | 8290 | } |
| 8291 | else if (it->bidi_it.charpos == bob | 8291 | else if (it->bidi_it.charpos == bob |
| 8292 | || (!string_p | 8292 | || (!string_p |
| 8293 | && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n' | 8293 | && (FETCH_BYTE (it->bidi_it.bytepos - 1) == '\n' |
| 8294 | || FETCH_CHAR (it->bidi_it.bytepos) == '\n'))) | 8294 | || FETCH_BYTE (it->bidi_it.bytepos) == '\n'))) |
| 8295 | { | 8295 | { |
| 8296 | /* If we are at the beginning of a line/string, we can produce | 8296 | /* If we are at the beginning of a line/string, we can produce |
| 8297 | the next element right away. */ | 8297 | the next element right away. */ |
| @@ -15566,6 +15566,12 @@ redisplay_internal (void) | |||
| 15566 | if (it.current_x != this_line_start_x) | 15566 | if (it.current_x != this_line_start_x) |
| 15567 | goto cancel; | 15567 | goto cancel; |
| 15568 | 15568 | ||
| 15569 | /* Give up on this optimization if the line starts with a | ||
| 15570 | string with display property that draws on the fringes, | ||
| 15571 | as that might interfere with line-prefix display. */ | ||
| 15572 | if (it.sp > 1 | ||
| 15573 | && it.method == GET_FROM_IMAGE && it.image_id == -1) | ||
| 15574 | goto cancel; | ||
| 15569 | redisplay_trace ("trying display optimization 1\n"); | 15575 | redisplay_trace ("trying display optimization 1\n"); |
| 15570 | w->cursor.vpos = -1; | 15576 | w->cursor.vpos = -1; |
| 15571 | overlay_arrow_seen = false; | 15577 | overlay_arrow_seen = false; |
| @@ -20338,6 +20344,12 @@ try_window_id (struct window *w) | |||
| 20338 | 20344 | ||
| 20339 | if (! init_to_row_end (&it, w, last_unchanged_at_beg_row)) | 20345 | if (! init_to_row_end (&it, w, last_unchanged_at_beg_row)) |
| 20340 | GIVE_UP (18); | 20346 | GIVE_UP (18); |
| 20347 | /* Give up if the row starts with a display property that draws | ||
| 20348 | on the fringes, since that could prevent correct display of | ||
| 20349 | line-prefix and wrap-prefix. */ | ||
| 20350 | if (it.sp > 1 | ||
| 20351 | && it.method == GET_FROM_IMAGE && it.image_id == -1) | ||
| 20352 | GIVE_UP (26); | ||
| 20341 | start_pos = it.current.pos; | 20353 | start_pos = it.current.pos; |
| 20342 | 20354 | ||
| 20343 | /* Start displaying new lines in the desired matrix at the same | 20355 | /* Start displaying new lines in the desired matrix at the same |
| @@ -24182,7 +24194,7 @@ the `bidi-class' property of a character. */) | |||
| 24182 | itb.charpos = BEGV; | 24194 | itb.charpos = BEGV; |
| 24183 | itb.bytepos = BEGV_BYTE; | 24195 | itb.bytepos = BEGV_BYTE; |
| 24184 | } | 24196 | } |
| 24185 | else if (FETCH_CHAR (from_bpos - 1) == '\n') | 24197 | else if (FETCH_BYTE (from_bpos - 1) == '\n') |
| 24186 | { | 24198 | { |
| 24187 | itb.charpos = from_pos; | 24199 | itb.charpos = from_pos; |
| 24188 | itb.bytepos = from_bpos; | 24200 | itb.bytepos = from_bpos; |