commit 58430f29968a5661caff630d20dbbe7c864fe08d (HEAD, refs/remotes/origin/master) Author: Eli Zaretskii Date: Sun Apr 16 10:43:22 2017 +0300 Fix redisplay performance problems with some fonts * src/font.c (font_list_entities): Revert part of the changes introduced on Apr 2, 2014 to fix bug#17125. It turns out having zero_vector in the font-cache is an important indication that cannot be removed. (Bug#21028) diff --git a/src/font.c b/src/font.c index a929509752..dd6191b2b1 100644 --- a/src/font.c +++ b/src/font.c @@ -2777,21 +2777,27 @@ font_list_entities (struct frame *f, Lisp_Object spec) val = XCDR (val); else { - val = driver_list->driver->list (f, scratch_font_spec); - if (!NILP (val)) - { - Lisp_Object copy = copy_font_spec (scratch_font_spec); + Lisp_Object copy; - val = Fvconcat (1, &val); - ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type); - XSETCDR (cache, Fcons (Fcons (copy, val), XCDR (cache))); - } + val = driver_list->driver->list (f, scratch_font_spec); + /* We put zero_vector in the font-cache to indicate that + no fonts matching SPEC were found on the system. + Failure to have this indication in the font cache can + cause severe performance degradation in some rare + cases, see bug#21028. */ + if (NILP (val)) + val = zero_vector; + else + val = Fvconcat (1, &val); + copy = copy_font_spec (scratch_font_spec); + ASET (copy, FONT_TYPE_INDEX, driver_list->driver->type); + XSETCDR (cache, Fcons (Fcons (copy, val), XCDR (cache))); } - if (VECTORP (val) && ASIZE (val) > 0 + if (ASIZE (val) > 0 && (need_filtering || ! NILP (Vface_ignored_fonts))) val = font_delete_unmatched (val, need_filtering ? spec : Qnil, size); - if (VECTORP (val) && ASIZE (val) > 0) + if (ASIZE (val) > 0) list = Fcons (val, list); } commit f3b24e90dc9fad355102e1fdf2828ca33d447a07 Author: Eli Zaretskii Date: Sun Apr 16 10:27:23 2017 +0300 Add assertion to STRING_SET_CHARS * src/lisp.h (STRING_SET_CHARS): Add an assertion and commentary to prevent incorrect usage. For details, see this discussion: http://lists.gnu.org/archive/html/emacs-devel/2017-04/msg00412.html. diff --git a/src/lisp.h b/src/lisp.h index 678e261c1d..e0bad58f75 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1369,6 +1369,10 @@ SBYTES (Lisp_Object string) INLINE void STRING_SET_CHARS (Lisp_Object string, ptrdiff_t newsize) { + /* This function cannot change the size of data allocated for the + string when it was created. */ + eassert ((STRING_MULTIBYTE (string) && newsize <= SBYTES (string)) + || (!STRING_MULTIBYTE (string) && newsize == SCHARS (string))); XSTRING (string)->size = newsize; } commit 1bf7ca623b3d3e02617cf0b5f8d7f980384838d3 Author: Eli Zaretskii Date: Sun Apr 16 10:12:42 2017 +0300 Avoid compilation warnings on MS-Windows * src/w32term.c (w32_read_socket): Avoid compiler warnings about parentheses around assignment. * src/w32fns.c (w32_createwindow): Remove unused variable dwStyle. Use "|=" where appropriate. diff --git a/src/w32fns.c b/src/w32fns.c index 62798f269e..8dca03265b 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -2297,7 +2297,6 @@ w32_createwindow (struct frame *f, int *coords) { HWND hwnd = NULL, parent_hwnd = NULL; RECT rect; - DWORD dwStyle; int top, left; Lisp_Object border_width = Fcdr (Fassq (Qborder_width, f->param_alist)); @@ -2310,14 +2309,13 @@ w32_createwindow (struct frame *f, int *coords) { /* If we want a thin border, specify it here. */ if (NUMBERP (border_width) && (XINT (border_width) > 0)) - f->output_data.w32->dwStyle = - f->output_data.w32->dwStyle | WS_BORDER; + f->output_data.w32->dwStyle |= WS_BORDER; } else /* To decorate a child frame, list all needed elements. */ - f->output_data.w32->dwStyle = - f->output_data.w32->dwStyle | WS_THICKFRAME | WS_CAPTION - | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU; + f->output_data.w32->dwStyle |= (WS_THICKFRAME | WS_CAPTION + | WS_MAXIMIZEBOX | WS_MINIMIZEBOX + | WS_SYSMENU); } else if (FRAME_UNDECORATED (f)) { @@ -2327,14 +2325,13 @@ w32_createwindow (struct frame *f, int *coords) /* If we want a thin border, specify it here. */ if (NUMBERP (border_width) && (XINT (border_width) > 0)) - f->output_data.w32->dwStyle = - f->output_data.w32->dwStyle | WS_BORDER; + f->output_data.w32->dwStyle |= WS_BORDER; } else f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW; /* Always clip children. */ - f->output_data.w32->dwStyle = f->output_data.w32->dwStyle | WS_CLIPCHILDREN; + f->output_data.w32->dwStyle |= WS_CLIPCHILDREN; rect.left = rect.top = 0; rect.right = FRAME_PIXEL_WIDTH (f); diff --git a/src/w32term.c b/src/w32term.c index 1c3d243b62..36dc6364ae 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -5136,7 +5136,8 @@ w32_read_socket (struct terminal *terminal, } #endif - if (f = x_window_to_frame (dpyinfo, msg.msg.hwnd)) + f = x_window_to_frame (dpyinfo, msg.msg.hwnd); + if (f) x_clear_under_internal_border (f); check_visibility = 1; commit 0ef7f64407525a1e1bcc8aef4d1fd19a1cf60ec6 Author: Paul Eggert Date: Sat Apr 15 22:22:49 2017 -0700 Merge from gnulib This incorporates: 2017-04-14 intprops: try to avoid tickling similar bugs 2017-04-14 intprops: port to Oracle Studio 12.3 x86 * doc/misc/texinfo.tex, lib/intprops.h: Copy from gnulib. diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex index 7bcb27b76e..9cd73101c1 100644 --- a/doc/misc/texinfo.tex +++ b/doc/misc/texinfo.tex @@ -3,7 +3,7 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2017-03-25.14} +\def\texinfoversion{2017-04-14.11} % % Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, % 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, @@ -11595,6 +11595,9 @@ @def ^^M{@let^^M@secondlinenl}% % Definition for a newline in the main Texinfo file. @gdef @secondlinenl{@fixbackslash}% + % In case the first line has a whole-line command on it + @let@originalparsearg@parsearg + @def@parsearg{@fixbackslash@originalparsearg} }} {@catcode`@^=7 @catcode`@^^M=13% @@ -11615,6 +11618,7 @@ @catcode13=5 % regular end of line @enableemergencynewline @let@c=@texinfoc + @let@parsearg@originalparsearg % Also turn back on active characters that might appear in the input % file name, in case not using a pre-dumped format. @catcode`+=@active diff --git a/lib/intprops.h b/lib/intprops.h index 85ed61f8d8..1ea9647e16 100644 --- a/lib/intprops.h +++ b/lib/intprops.h @@ -389,10 +389,10 @@ verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH); (_Generic \ (*(r), \ signed char: \ - _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned char, \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ signed char, SCHAR_MIN, SCHAR_MAX), \ short int: \ - _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned short int, \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ short int, SHRT_MIN, SHRT_MAX), \ int: \ _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ @@ -406,10 +406,10 @@ verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH); #else # define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \ (sizeof *(r) == sizeof (signed char) \ - ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned char, \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ signed char, SCHAR_MIN, SCHAR_MAX) \ : sizeof *(r) == sizeof (short int) \ - ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned short int, \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ short int, SHRT_MIN, SHRT_MAX) \ : sizeof *(r) == sizeof (int) \ ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ @@ -431,9 +431,8 @@ verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH); /* Store the low-order bits of A B into *R, where the operation is given by OP. Use the unsigned type UT for calculation to avoid - overflow problems. *R's type is T, with extremal values TMIN and - TMAX. T must be a signed integer type. Return 1 if the result - overflows. */ + overflow problems. *R's type is T, with extrema TMIN and TMAX. + T must be a signed integer type. Return 1 if the result overflows. */ #define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \ (sizeof ((a) op (b)) < sizeof (t) \ ? _GL_INT_OP_CALC1 ((t) (a), (t) (b), r, op, overflow, ut, t, tmin, tmax) \ @@ -442,17 +441,27 @@ verify (TYPE_WIDTH (unsigned int) == UINT_WIDTH); ((overflow (a, b) \ || (EXPR_SIGNED ((a) op (b)) && ((a) op (b)) < (tmin)) \ || (tmax) < ((a) op (b))) \ - ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t, tmin, tmax), 1) \ - : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t, tmin, tmax), 0)) - -/* Return A B, where the operation is given by OP. Use the - unsigned type UT for calculation to avoid overflow problems. - Convert the result to type T without overflow by subtracting TMIN - from large values before converting, and adding it afterwards. - Compilers can optimize all the operations except OP. */ -#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t, tmin, tmax) \ - (((ut) (a) op (ut) (b)) <= (tmax) \ - ? (t) ((ut) (a) op (ut) (b)) \ - : ((t) (((ut) (a) op (ut) (b)) - (tmin)) + (tmin))) + ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \ + : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0)) + +/* Return the low-order bits of A B, where the operation is given + by OP. Use the unsigned type UT for calculation to avoid undefined + behavior on signed integer overflow, and convert the result to type T. + UT is at least as wide as T and is no narrower than unsigned int, + T is two's complement, and there is no padding or trap representations. + Assume that converting UT to T yields the low-order bits, as is + done in all known two's-complement C compilers. E.g., see: + https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html + + According to the C standard, converting UT to T yields an + implementation-defined result or signal for values outside T's + range. However, code that works around this theoretical problem + runs afoul of a compiler bug in Oracle Studio 12.3 x86. See: + http://lists.gnu.org/archive/html/bug-gnulib/2017-04/msg00049.html + As the compiler bug is real, don't try to work around the + theoretical problem. */ + +#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \ + ((t) ((ut) (a) op (ut) (b))) #endif /* _GL_INTPROPS_H */ commit 23d3eeb798c7edc27898b0dbd4c2364a6ca6247d Author: Martin Rudalics Date: Sat Apr 15 16:16:26 2017 +0200 Fix bugs in `with-displayed-buffer-window' and `fit-window-to-buffer' * lisp/window.el (with-displayed-buffer-window): When a 'window-height' action alist entry specifies a function, call `temp-buffer-window-show' with a '(window-height . t)' dummy entry so `window--try-to-split-window' will bind `window-combination-limit' to t and that function does not resize any other window but the one we split this one off (Bug#25055, Bug#25179). (fit-window-to-buffer): Call `window-max-delta' with NOUP t so we steal space only from windows in the same combination. Stealing space from other windows would not allow us to return that space later when this window is deleted (Bug#25055, Bug#25179). diff --git a/lisp/window.el b/lisp/window.el index f4a834c0d8..8b07ed462c 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -235,14 +235,27 @@ displays the buffer specified by BUFFER-OR-NAME before running BODY." (vquit-function quit-function)) `(let* ((,buffer (temp-buffer-window-setup ,vbuffer-or-name)) (standard-output ,buffer) + ;; If a 'window-height' entry specifies a function, + ;; remember it here in order to call it below but replace + ;; the entry so `window--try-to-split-window' will bind + ;; `window-combination-limit' to t and the function does + ;; not resize any other window but the one we split this + ;; one off (Bug#25055, Bug#25179). + (vheight-function + (let ((window-height (assq 'window-height (cdr ,vaction)))) + (when (functionp (cdr window-height)) + (cdr window-height)))) + (vaction-copied + (when vheight-function + (cons (car , vaction) + (cons + '(window-height . t) + (assq-delete-all + 'window-height (cdr (copy-sequence ,vaction))))))) ,window ,value) (with-current-buffer ,buffer (setq ,window (temp-buffer-window-show - ,buffer - ;; Remove window-height when it's handled below. - (if (functionp (cdr (assq 'window-height (cdr ,vaction)))) - (assq-delete-all 'window-height (copy-sequence ,vaction)) - ,vaction)))) + ,buffer (or vaction-copied ,vaction)))) (let ((inhibit-read-only t) (inhibit-modification-hooks t)) @@ -250,9 +263,10 @@ displays the buffer specified by BUFFER-OR-NAME before running BODY." (set-window-point ,window (point-min)) - (when (functionp (cdr (assq 'window-height (cdr ,vaction)))) + (when vheight-function (ignore-errors - (funcall (cdr (assq 'window-height (cdr ,vaction))) ,window))) + (set-window-parameter ,window 'preserve-size nil) + (funcall vheight-function ,window))) (when (consp (cdr (assq 'preserve-size (cdr ,vaction)))) (window-preserve-size @@ -8152,12 +8166,12 @@ accessible position." (min (+ total-height (window-max-delta - window nil window nil nil nil pixelwise)) + window nil window nil t nil pixelwise)) (if pixelwise (* char-height max-height) max-height)) (+ total-height (window-max-delta - window nil window nil nil nil pixelwise)))) + window nil window nil t nil pixelwise)))) height) (cond ;; If WINDOW is vertically combined, try to resize it @@ -8209,12 +8223,12 @@ accessible position." (if (numberp max-width) (min (+ total-width (window-max-delta - window t window nil nil nil pixelwise)) + window t window nil t nil pixelwise)) (if pixelwise (* char-width max-width) max-width)) (+ total-width (window-max-delta - window t window nil nil nil pixelwise)))) + window t window nil t nil pixelwise)))) ;; When fitting horizontally, assume that WINDOW's ;; start position remains unaltered. WINDOW can't get ;; wider than its frame's pixel width, its height