aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGlenn Morris2018-07-02 19:19:26 -0700
committerGlenn Morris2018-07-02 19:19:26 -0700
commit02f2f336af7c4129ec79ab00881bba3e14ff9820 (patch)
tree3f279977bb231ea6ddab8680999bc1bffcb31071 /src
parentbc0e36df8d33595d6411ec4c18e3f4b643c01306 (diff)
parentfc5cae731cede7e00f3f2d40d6577537f872d439 (diff)
downloademacs-02f2f336af7c4129ec79ab00881bba3e14ff9820.tar.gz
emacs-02f2f336af7c4129ec79ab00881bba3e14ff9820.zip
Merge from origin/emacs-26
fc5cae7 ; Fix ChangeLog typo. e17a5e5 ; make change-history-commit f205928 * etc/HISTORY: Cite Brinkoff on early history. 4e58ca8 Document internal use of 'above-suspended' z-group frame para... 4bd43b0 Increase max-lisp-eval-depth adjustment while in debugger (bu... ab98352 Improve on last change in replace-buffer-contents 2f149c0 Fix a factual error in Introduction to Emacs Lisp 8ad50a3 ; * lisp/files.el (buffer-offer-save): Doc fix. (Bug#32000) c80f31f Minor improvements in documentation of imenu.el 8ebb683 Avoid errors with recentering in 'skeleton-insert' e980a3c * src/lisp.h: Omit obsolete comment re bytecode stack. eec71eb Speed up replace-buffer-contents 93c41ce Remove extra process call from vc-git-find-file-hook 7ea0873 ; Update some commentary 4a7f423 Speed up vc-git-dir-status-files 9134c84 Avoid compiler warning using coding.h Conflicts: src/editfns.c
Diffstat (limited to 'src')
-rw-r--r--src/coding.h4
-rw-r--r--src/editfns.c99
-rw-r--r--src/eval.c8
-rw-r--r--src/lisp.h18
-rw-r--r--src/w32fns.c22
-rw-r--r--src/xterm.c4
6 files changed, 116 insertions, 39 deletions
diff --git a/src/coding.h b/src/coding.h
index 165c1b29b71..d2cf4d8a7ba 100644
--- a/src/coding.h
+++ b/src/coding.h
@@ -28,6 +28,8 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
28 28
29#include "lisp.h" 29#include "lisp.h"
30 30
31INLINE_HEADER_BEGIN
32
31/* Index to arguments of Fdefine_coding_system_internal. */ 33/* Index to arguments of Fdefine_coding_system_internal. */
32 34
33enum define_coding_system_arg_index 35enum define_coding_system_arg_index
@@ -771,4 +773,6 @@ extern struct coding_system safe_terminal_coding;
771 773
772extern char emacs_mule_bytes[256]; 774extern char emacs_mule_bytes[256];
773 775
776INLINE_HEADER_END
777
774#endif /* EMACS_CODING_H */ 778#endif /* EMACS_CODING_H */
diff --git a/src/editfns.c b/src/editfns.c
index efe83e811ba..e16a554de20 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3127,6 +3127,9 @@ determines whether case is significant or ignored. */)
3127#undef ELEMENT 3127#undef ELEMENT
3128#undef EQUAL 3128#undef EQUAL
3129 3129
3130/* Counter used to rarely_quit in replace-buffer-contents. */
3131static unsigned short rbc_quitcounter;
3132
3130#define XVECREF_YVECREF_EQUAL(ctx, xoff, yoff) \ 3133#define XVECREF_YVECREF_EQUAL(ctx, xoff, yoff) \
3131 buffer_chars_equal ((ctx), (xoff), (yoff)) 3134 buffer_chars_equal ((ctx), (xoff), (yoff))
3132 3135
@@ -3136,6 +3139,9 @@ determines whether case is significant or ignored. */)
3136 /* Buffers to compare. */ \ 3139 /* Buffers to compare. */ \
3137 struct buffer *buffer_a; \ 3140 struct buffer *buffer_a; \
3138 struct buffer *buffer_b; \ 3141 struct buffer *buffer_b; \
3142 /* Whether each buffer is unibyte/plain-ASCII or not. */ \
3143 bool a_unibyte; \
3144 bool b_unibyte; \
3139 /* Bit vectors recording for each character whether it was deleted 3145 /* Bit vectors recording for each character whether it was deleted
3140 or inserted. */ \ 3146 or inserted. */ \
3141 unsigned char *deletions; \ 3147 unsigned char *deletions; \
@@ -3216,6 +3222,8 @@ differences between the two buffers. */)
3216 struct context ctx = { 3222 struct context ctx = {
3217 .buffer_a = a, 3223 .buffer_a = a,
3218 .buffer_b = b, 3224 .buffer_b = b,
3225 .a_unibyte = BUF_ZV (a) == BUF_ZV_BYTE (a),
3226 .b_unibyte = BUF_ZV (b) == BUF_ZV_BYTE (b),
3219 .deletions = SAFE_ALLOCA (del_bytes), 3227 .deletions = SAFE_ALLOCA (del_bytes),
3220 .insertions = SAFE_ALLOCA (ins_bytes), 3228 .insertions = SAFE_ALLOCA (ins_bytes),
3221 .fdiag = buffer + size_b + 1, 3229 .fdiag = buffer + size_b + 1,
@@ -3232,9 +3240,36 @@ differences between the two buffers. */)
3232 early. */ 3240 early. */
3233 eassert (! early_abort); 3241 eassert (! early_abort);
3234 3242
3243 rbc_quitcounter = 0;
3244
3235 Fundo_boundary (); 3245 Fundo_boundary ();
3246 bool modification_hooks_inhibited = false;
3236 record_unwind_protect_excursion (); 3247 record_unwind_protect_excursion ();
3237 3248
3249 /* We are going to make a lot of small modifications, and having the
3250 modification hooks called for each of them will slow us down.
3251 Instead, we announce a single modification for the entire
3252 modified region. But don't do that if the caller inhibited
3253 modification hooks, because then they don't want that. */
3254 ptrdiff_t from, to;
3255 if (!inhibit_modification_hooks)
3256 {
3257 ptrdiff_t k, l;
3258
3259 /* Find the first character position to be changed. */
3260 for (k = 0; k < size_a && !bit_is_set (ctx.deletions, k); k++)
3261 ;
3262 from = BEGV + k;
3263
3264 /* Find the last character position to be changed. */
3265 for (l = size_a; l > 0 && !bit_is_set (ctx.deletions, l - 1); l--)
3266 ;
3267 to = BEGV + l;
3268 prepare_to_modify_buffer (from, to, NULL);
3269 specbind (Qinhibit_modification_hooks, Qt);
3270 modification_hooks_inhibited = true;
3271 }
3272
3238 ptrdiff_t i = size_a; 3273 ptrdiff_t i = size_a;
3239 ptrdiff_t j = size_b; 3274 ptrdiff_t j = size_b;
3240 /* Walk backwards through the lists of changes. This was also 3275 /* Walk backwards through the lists of changes. This was also
@@ -3243,15 +3278,13 @@ differences between the two buffers. */)
3243 while (i >= 0 || j >= 0) 3278 while (i >= 0 || j >= 0)
3244 { 3279 {
3245 /* Allow the user to quit if this gets too slow. */ 3280 /* Allow the user to quit if this gets too slow. */
3246 maybe_quit (); 3281 rarely_quit (++rbc_quitcounter);
3247 3282
3248 /* Check whether there is a change (insertion or deletion) 3283 /* Check whether there is a change (insertion or deletion)
3249 before the current position. */ 3284 before the current position. */
3250 if ((i > 0 && bit_is_set (ctx.deletions, i - 1)) || 3285 if ((i > 0 && bit_is_set (ctx.deletions, i - 1)) ||
3251 (j > 0 && bit_is_set (ctx.insertions, j - 1))) 3286 (j > 0 && bit_is_set (ctx.insertions, j - 1)))
3252 { 3287 {
3253 maybe_quit ();
3254
3255 ptrdiff_t end_a = min_a + i; 3288 ptrdiff_t end_a = min_a + i;
3256 ptrdiff_t end_b = min_b + j; 3289 ptrdiff_t end_b = min_b + j;
3257 /* Find the beginning of the current change run. */ 3290 /* Find the beginning of the current change run. */
@@ -3259,14 +3292,13 @@ differences between the two buffers. */)
3259 --i; 3292 --i;
3260 while (j > 0 && bit_is_set (ctx.insertions, j - 1)) 3293 while (j > 0 && bit_is_set (ctx.insertions, j - 1))
3261 --j; 3294 --j;
3295
3296 rarely_quit (rbc_quitcounter++);
3297
3262 ptrdiff_t beg_a = min_a + i; 3298 ptrdiff_t beg_a = min_a + i;
3263 ptrdiff_t beg_b = min_b + j; 3299 ptrdiff_t beg_b = min_b + j;
3264 eassert (beg_a >= BEGV);
3265 eassert (beg_b >= BUF_BEGV (b));
3266 eassert (beg_a <= end_a); 3300 eassert (beg_a <= end_a);
3267 eassert (beg_b <= end_b); 3301 eassert (beg_b <= end_b);
3268 eassert (end_a <= ZV);
3269 eassert (end_b <= BUF_ZV (b));
3270 eassert (beg_a < end_a || beg_b < end_b); 3302 eassert (beg_a < end_a || beg_b < end_b);
3271 if (beg_a < end_a) 3303 if (beg_a < end_a)
3272 del_range (beg_a, end_a); 3304 del_range (beg_a, end_a);
@@ -3280,8 +3312,17 @@ differences between the two buffers. */)
3280 --i; 3312 --i;
3281 --j; 3313 --j;
3282 } 3314 }
3315 SAFE_FREE_UNBIND_TO (count, Qnil);
3316 rbc_quitcounter = 0;
3283 3317
3284 return SAFE_FREE_UNBIND_TO (count, Qnil); 3318 if (modification_hooks_inhibited)
3319 {
3320 ptrdiff_t updated_to = to + ZV - BEGV - size_a;
3321 signal_after_change (from, to - from, updated_to - from);
3322 update_compositions (from, updated_to, CHECK_INSIDE);
3323 }
3324
3325 return Qnil;
3285} 3326}
3286 3327
3287static void 3328static void
@@ -3307,39 +3348,45 @@ bit_is_set (const unsigned char *a, ptrdiff_t i)
3307/* Return true if the characters at position POS_A of buffer 3348/* Return true if the characters at position POS_A of buffer
3308 CTX->buffer_a and at position POS_B of buffer CTX->buffer_b are 3349 CTX->buffer_a and at position POS_B of buffer CTX->buffer_b are
3309 equal. POS_A and POS_B are zero-based. Text properties are 3350 equal. POS_A and POS_B are zero-based. Text properties are
3310 ignored. */ 3351 ignored.
3352
3353 Implementation note: this function is called inside the inner-most
3354 loops of compareseq, so it absolutely must be optimized for speed,
3355 every last bit of it. E.g., each additional use of BEGV or such
3356 likes will slow down replace-buffer-contents by dozens of percents,
3357 because builtin_lisp_symbol will be called one more time in the
3358 innermost loop. */
3311 3359
3312static bool 3360static bool
3313buffer_chars_equal (struct context *ctx, 3361buffer_chars_equal (struct context *ctx,
3314 ptrdiff_t pos_a, ptrdiff_t pos_b) 3362 ptrdiff_t pos_a, ptrdiff_t pos_b)
3315{ 3363{
3316 eassert (pos_a >= 0);
3317 pos_a += BUF_BEGV (ctx->buffer_a); 3364 pos_a += BUF_BEGV (ctx->buffer_a);
3318 eassert (pos_a >= BUF_BEGV (ctx->buffer_a));
3319 eassert (pos_a < BUF_ZV (ctx->buffer_a));
3320
3321 eassert (pos_b >= 0);
3322 pos_b += BUF_BEGV (ctx->buffer_b); 3365 pos_b += BUF_BEGV (ctx->buffer_b);
3323 eassert (pos_b >= BUF_BEGV (ctx->buffer_b));
3324 eassert (pos_b < BUF_ZV (ctx->buffer_b));
3325
3326 bool a_unibyte = BUF_ZV (ctx->buffer_a) == BUF_ZV_BYTE (ctx->buffer_a);
3327 bool b_unibyte = BUF_ZV (ctx->buffer_b) == BUF_ZV_BYTE (ctx->buffer_b);
3328 3366
3329 /* Allow the user to escape out of a slow compareseq call. */ 3367 /* Allow the user to escape out of a slow compareseq call. */
3330 maybe_quit (); 3368 rarely_quit (++rbc_quitcounter);
3331 3369
3332 ptrdiff_t bpos_a = 3370 ptrdiff_t bpos_a =
3333 a_unibyte ? pos_a : buf_charpos_to_bytepos (ctx->buffer_a, pos_a); 3371 ctx->a_unibyte ? pos_a : buf_charpos_to_bytepos (ctx->buffer_a, pos_a);
3334 ptrdiff_t bpos_b = 3372 ptrdiff_t bpos_b =
3335 b_unibyte ? pos_b : buf_charpos_to_bytepos (ctx->buffer_b, pos_b); 3373 ctx->b_unibyte ? pos_b : buf_charpos_to_bytepos (ctx->buffer_b, pos_b);
3336 3374
3337 if (a_unibyte && b_unibyte) 3375 /* We make the below a series of specific test to avoid using
3376 BUF_FETCH_CHAR_AS_MULTIBYTE, which references Lisp symbols, and
3377 is therefore significantly slower (see the note in the commentary
3378 to this function). */
3379 if (ctx->a_unibyte && ctx->b_unibyte)
3338 return BUF_FETCH_BYTE (ctx->buffer_a, bpos_a) 3380 return BUF_FETCH_BYTE (ctx->buffer_a, bpos_a)
3339 == BUF_FETCH_BYTE (ctx->buffer_b, bpos_b); 3381 == BUF_FETCH_BYTE (ctx->buffer_b, bpos_b);
3340 3382 if (ctx->a_unibyte && !ctx->b_unibyte)
3341 return BUF_FETCH_CHAR_AS_MULTIBYTE (ctx->buffer_a, bpos_a) 3383 return UNIBYTE_TO_CHAR (BUF_FETCH_BYTE (ctx->buffer_a, bpos_a))
3342 == BUF_FETCH_CHAR_AS_MULTIBYTE (ctx->buffer_b, bpos_b); 3384 == BUF_FETCH_MULTIBYTE_CHAR (ctx->buffer_b, bpos_b);
3385 if (!ctx->a_unibyte && ctx->b_unibyte)
3386 return BUF_FETCH_MULTIBYTE_CHAR (ctx->buffer_a, bpos_a)
3387 == UNIBYTE_TO_CHAR (BUF_FETCH_BYTE (ctx->buffer_b, bpos_b));
3388 return BUF_FETCH_MULTIBYTE_CHAR (ctx->buffer_a, bpos_a)
3389 == BUF_FETCH_MULTIBYTE_CHAR (ctx->buffer_b, bpos_b);
3343} 3390}
3344 3391
3345 3392
diff --git a/src/eval.c b/src/eval.c
index c16a267bc5e..256ca8ffdc8 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -282,8 +282,12 @@ call_debugger (Lisp_Object arg)
282 /* Do not allow max_specpdl_size less than actual depth (Bug#16603). */ 282 /* Do not allow max_specpdl_size less than actual depth (Bug#16603). */
283 EMACS_INT old_max = max (max_specpdl_size, count); 283 EMACS_INT old_max = max (max_specpdl_size, count);
284 284
285 if (lisp_eval_depth + 40 > max_lisp_eval_depth) 285 /* The previous value of 40 is too small now that the debugger
286 max_lisp_eval_depth = lisp_eval_depth + 40; 286 prints using cl-prin1 instead of prin1. Printing lists nested 8
287 deep (which is the value of print-level used in the debugger)
288 currently requires 77 additional frames. See bug#31919. */
289 if (lisp_eval_depth + 100 > max_lisp_eval_depth)
290 max_lisp_eval_depth = lisp_eval_depth + 100;
287 291
288 /* While debugging Bug#16603, previous value of 100 was found 292 /* While debugging Bug#16603, previous value of 100 was found
289 too small to avoid specpdl overflow in the debugger itself. */ 293 too small to avoid specpdl overflow in the debugger itself. */
diff --git a/src/lisp.h b/src/lisp.h
index 6203a746a30..731a45da11a 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3012,15 +3012,13 @@ extern void defvar_kboard (struct Lisp_Kboard_Objfwd *, const char *, int);
3012 } while (false) 3012 } while (false)
3013 3013
3014 3014
3015/* Elisp uses several stacks: 3015/* Elisp uses multiple stacks:
3016 - the C stack. 3016 - The C stack.
3017 - the bytecode stack: used internally by the bytecode interpreter. 3017 - The specpdl stack keeps track of backtraces, unwind-protects and
3018 Allocated from the C stack. 3018 dynamic let-bindings. It is allocated from the 'specpdl' array,
3019 - The specpdl stack: keeps track of active unwind-protect and 3019 a manually managed stack.
3020 dynamic-let-bindings. Allocated from the `specpdl' array, a manually 3020 - The handler stack keeps track of active catch tags and condition-case
3021 managed stack. 3021 handlers. It is allocated in a manually managed stack implemented by a
3022 - The handler stack: keeps track of active catch tags and condition-case
3023 handlers. Allocated in a manually managed stack implemented by a
3024 doubly-linked list allocated via xmalloc and never freed. */ 3022 doubly-linked list allocated via xmalloc and never freed. */
3025 3023
3026/* Structure for recording Lisp call stack for backtrace purposes. */ 3024/* Structure for recording Lisp call stack for backtrace purposes. */
@@ -3113,7 +3111,7 @@ SPECPDL_INDEX (void)
3113 control structures. A struct handler contains all the information needed to 3111 control structures. A struct handler contains all the information needed to
3114 restore the state of the interpreter after a non-local jump. 3112 restore the state of the interpreter after a non-local jump.
3115 3113
3116 handler structures are chained together in a doubly linked list; the `next' 3114 Handler structures are chained together in a doubly linked list; the `next'
3117 member points to the next outer catchtag and the `nextfree' member points in 3115 member points to the next outer catchtag and the `nextfree' member points in
3118 the other direction to the next inner element (which is typically the next 3116 the other direction to the next inner element (which is typically the next
3119 free element since we mostly use it on the deepest handler). 3117 free element since we mostly use it on the deepest handler).
diff --git a/src/w32fns.c b/src/w32fns.c
index 3bd320928dd..7f7e1a404ce 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -2192,6 +2192,11 @@ x_set_no_accept_focus (struct frame *f, Lisp_Object new_value, Lisp_Object old_v
2192 * 2192 *
2193 * Some window managers may not honor this parameter. The value `below' 2193 * Some window managers may not honor this parameter. The value `below'
2194 * is not supported on Windows. 2194 * is not supported on Windows.
2195 *
2196 * Internally, this function also handles a value 'above-suspended'.
2197 * That value is used to temporarily remove F from the 'above' group
2198 * to make sure that it does not obscure the window of a dialog in
2199 * progress.
2195 */ 2200 */
2196static void 2201static void
2197x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) 2202x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
@@ -7583,12 +7588,27 @@ file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
7583 return 0; 7588 return 0;
7584} 7589}
7585 7590
7591/**
7592 * w32_dialog_in_progress:
7593 *
7594 * This function is called by Fx_file_dialog and Fx_select_font and
7595 * serves to temporarily remove any Emacs frame currently in the
7596 * 'above' z-group from that group to assure that such a frame does
7597 * not hide the dialog window. Frames that are temporarily removed
7598 * from the 'above' group have their z_group bit-field set to
7599 * z_group_above_suspended. Any such frame is moved back to the
7600 * 'above' group as soon as the dialog finishes and has its z_group
7601 * bit-field reset to z_group_above.
7602 *
7603 * This function does not affect the z-order or the z-group state of
7604 * the dialog window itself.
7605 */
7586void 7606void
7587w32_dialog_in_progress (Lisp_Object in_progress) 7607w32_dialog_in_progress (Lisp_Object in_progress)
7588{ 7608{
7589 Lisp_Object frames, frame; 7609 Lisp_Object frames, frame;
7590 7610
7591 /* Don't let frames in `above' z-group obscure popups. */ 7611 /* Don't let frames in `above' z-group obscure dialog windows. */
7592 FOR_EACH_FRAME (frames, frame) 7612 FOR_EACH_FRAME (frames, frame)
7593 { 7613 {
7594 struct frame *f = XFRAME (frame); 7614 struct frame *f = XFRAME (frame);
diff --git a/src/xterm.c b/src/xterm.c
index 9504bfb1834..af28dab860a 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -10566,6 +10566,10 @@ x_set_skip_taskbar (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
10566 * windows that do not have the `below' property set. 10566 * windows that do not have the `below' property set.
10567 * 10567 *
10568 * Some window managers may not honor this parameter. 10568 * Some window managers may not honor this parameter.
10569 *
10570 * Internally, this function also handles a value 'above-suspended'.
10571 * That value is used to temporarily remove F from the 'above' group
10572 * to make sure that it does not obscure a menu currently popped up.
10569 */ 10573 */
10570void 10574void
10571x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) 10575x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)