From fb7677be03e8c49d6a549f0d993b4df6f0ea404d Mon Sep 17 00:00:00 2001 Message-ID: From: Ihor Radchenko Date: Fri, 15 Dec 2023 11:47:45 +0100 Subject: [PATCH] Improve performance let-binding `case-fold-search' (bug#66117) * src/buffer.h: Remove case_fold_search_ buffer object slot. * src/buffer.c (bset_case_fold_search): Remove - no longer needed. (init_buffer_once): Remove removed buffer slot init. (syms_of_buffer): Use DEFVAR_LISP to define `case-fold-search' and declare it buffer-local. * src/minibuf.c (syms_of_minibuf): Remove DEFSYM call for `case-fold-search' symbol. It now lives in `syms_of_buffer'. * src/editfns.c (Fcompare_buffer_substrings): (Fchar_equal): * src/search.c (looking_at_1): (string_match_1): (search_command): (Fre__describe_compiled): Adjust C queries to `case-fold-search' value to use C globals instead of BVAR macro. * doc/lispref/internals.texi (Buffer Internals): Do not list `case_fold_search' slot. See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=66117#259 When used as buffer slot, let-binding `case-fold-search' would scale with the number of live buffers and can be slow. This change makes let-binding much faster at the cost of slightly slower `set-buffer'. --- doc/lispref/internals.texi | 1 - src/buffer.c | 17 ++++++----------- src/buffer.h | 1 - src/editfns.c | 4 ++-- src/minibuf.c | 1 - src/search.c | 10 +++++----- 6 files changed, 13 insertions(+), 21 deletions(-) diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi index 1fba683223e..4b4edda6d46 100644 --- a/doc/lispref/internals.texi +++ b/doc/lispref/internals.texi @@ -2519,7 +2519,6 @@ Buffer Internals @item mode_line_format @itemx header_line_format -@itemx case_fold_search @itemx tab_width @itemx fill_column @itemx left_margin diff --git a/src/buffer.c b/src/buffer.c index 12f226d8249..919c470d9e5 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -210,11 +210,6 @@ bset_buffer_file_coding_system (struct buffer *b, Lisp_Object val) b->buffer_file_coding_system_ = val; } static void -bset_case_fold_search (struct buffer *b, Lisp_Object val) -{ - b->case_fold_search_ = val; -} -static void bset_ctl_arrow (struct buffer *b, Lisp_Object val) { b->ctl_arrow_ = val; @@ -4692,7 +4687,6 @@ init_buffer_once (void) XSETFASTINT (BVAR (&buffer_local_flags, mode_line_format), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, abbrev_mode), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, overwrite_mode), idx); ++idx; - XSETFASTINT (BVAR (&buffer_local_flags, case_fold_search), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, auto_fill_function), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, selective_display), idx); ++idx; XSETFASTINT (BVAR (&buffer_local_flags, selective_display_ellipses), idx); ++idx; @@ -4785,7 +4779,6 @@ init_buffer_once (void) bset_tab_line_format (&buffer_defaults, Qnil); bset_abbrev_mode (&buffer_defaults, Qnil); bset_overwrite_mode (&buffer_defaults, Qnil); - bset_case_fold_search (&buffer_defaults, Qt); bset_auto_fill_function (&buffer_defaults, Qnil); bset_selective_display (&buffer_defaults, Qnil); bset_selective_display_ellipses (&buffer_defaults, Qt); @@ -5215,10 +5208,6 @@ syms_of_buffer (void) doc: /* Non-nil if Abbrev mode is enabled. Use the command `abbrev-mode' to change this variable. */); - DEFVAR_PER_BUFFER ("case-fold-search", &BVAR (current_buffer, case_fold_search), - Qnil, - doc: /* Non-nil if searches and matches should ignore case. */); - DEFVAR_PER_BUFFER ("fill-column", &BVAR (current_buffer, fill_column), Qintegerp, doc: /* Column beyond which automatic line-wrapping should happen. @@ -5951,6 +5940,12 @@ Functions (implicitly) running this hook are `get-buffer-create', This is the default. If nil, auto-save file deletion is inhibited. */); delete_auto_save_files = 1; + DEFVAR_LISP ("case-fold-search", Vcase_fold_search, + doc: /* Non-nil if searches and matches should ignore case. */); + Vcase_fold_search = Qt; + DEFSYM (Qcase_fold_search, "case-fold-search"); + Fmake_variable_buffer_local (Qcase_fold_search); + DEFVAR_LISP ("clone-indirect-buffer-hook", Vclone_indirect_buffer_hook, doc: /* Normal hook to run in the new buffer at the end of `make-indirect-buffer'. diff --git a/src/buffer.h b/src/buffer.h index b2bd15657dc..399c6585158 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -379,7 +379,6 @@ #define BVAR(buf, field) ((buf)->field ## _) /* Values of several buffer-local variables. */ /* tab-width is buffer-local so that redisplay can find it in buffers that are not current. */ - Lisp_Object case_fold_search_; Lisp_Object tab_width_; Lisp_Object fill_column_; Lisp_Object left_margin_; diff --git a/src/editfns.c b/src/editfns.c index 49d552c4a75..aa410ea7091 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -1785,7 +1785,7 @@ DEFUN ("compare-buffer-substrings", Fcompare_buffer_substrings, Scompare_buffer_ register EMACS_INT begp1, endp1, begp2, endp2, temp; register struct buffer *bp1, *bp2; register Lisp_Object trt - = (!NILP (BVAR (current_buffer, case_fold_search)) + = (!NILP (Vcase_fold_search) ? BVAR (current_buffer, case_canon_table) : Qnil); ptrdiff_t chars = 0; ptrdiff_t i1, i2, i1_byte, i2_byte; @@ -4367,7 +4367,7 @@ DEFUN ("char-equal", Fchar_equal, Schar_equal, 2, 2, 0, if (XFIXNUM (c1) == XFIXNUM (c2)) return Qt; - if (NILP (BVAR (current_buffer, case_fold_search))) + if (NILP (Vcase_fold_search)) return Qnil; i1 = XFIXNAT (c1); diff --git a/src/minibuf.c b/src/minibuf.c index 58adde1bf66..0d5b375e450 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -2320,7 +2320,6 @@ syms_of_minibuf (void) DEFSYM (Qcurrent_input_method, "current-input-method"); DEFSYM (Qactivate_input_method, "activate-input-method"); - DEFSYM (Qcase_fold_search, "case-fold-search"); DEFSYM (Qmetadata, "metadata"); DEFSYM (Qcycle_sort_function, "cycle-sort-function"); diff --git a/src/search.c b/src/search.c index 2996d32fca1..75a67ff3223 100644 --- a/src/search.c +++ b/src/search.c @@ -281,7 +281,7 @@ looking_at_1 (Lisp_Object string, bool posix, bool modify_data) struct regexp_cache *cache_entry = compile_pattern ( string, modify_match_data ? &search_regs : NULL, - (!NILP (BVAR (current_buffer, case_fold_search)) + (!NILP (Vcase_fold_search) ? BVAR (current_buffer, case_canon_table) : Qnil), posix, !NILP (BVAR (current_buffer, enable_multibyte_characters))); @@ -402,7 +402,7 @@ string_match_1 (Lisp_Object regexp, Lisp_Object string, Lisp_Object start, struct regexp_cache *cache_entry = compile_pattern (regexp, modify_match_data ? &search_regs : NULL, - (!NILP (BVAR (current_buffer, case_fold_search)) + (!NILP (Vcase_fold_search) ? BVAR (current_buffer, case_canon_table) : Qnil), posix, @@ -1068,10 +1068,10 @@ search_command (Lisp_Object string, Lisp_Object bound, Lisp_Object noerror, BVAR (current_buffer, case_eqv_table)); np = search_buffer (string, PT, PT_BYTE, lim, lim_byte, n, RE, - (!NILP (BVAR (current_buffer, case_fold_search)) + (!NILP (Vcase_fold_search) ? BVAR (current_buffer, case_canon_table) : Qnil), - (!NILP (BVAR (current_buffer, case_fold_search)) + (!NILP (Vcase_fold_search) ? BVAR (current_buffer, case_eqv_table) : Qnil), posix); @@ -3402,7 +3402,7 @@ DEFUN ("re--describe-compiled", Fre__describe_compiled, Sre__describe_compiled, { struct regexp_cache *cache_entry = compile_pattern (regexp, NULL, - (!NILP (BVAR (current_buffer, case_fold_search)) + (!NILP (Vcase_fold_search) ? BVAR (current_buffer, case_canon_table) : Qnil), false, !NILP (BVAR (current_buffer, -- 2.42.0