From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Spencer Baugh Newsgroups: gmane.emacs.bugs Subject: bug#48264: [PATCH v3 08/15] Set non-buffer-local BVARs to Qunbound Date: Thu, 6 May 2021 17:33:39 -0400 Message-ID: <20210506213346.9730-9-sbaugh@catern.com> References: <877dkbsj9d.fsf@catern.com> Mime-Version: 1.0 Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="3428"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Spencer Baugh To: 48264@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Thu May 06 23:35:56 2021 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lelf1-0000kg-F8 for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 06 May 2021 23:35:55 +0200 Original-Received: from localhost ([::1]:34716 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lelf0-0006Vw-FF for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 06 May 2021 17:35:54 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:45582) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1leleB-0006Ur-Ro for bug-gnu-emacs@gnu.org; Thu, 06 May 2021 17:35:03 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:56584) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1leleB-0002QP-Ag for bug-gnu-emacs@gnu.org; Thu, 06 May 2021 17:35:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1leleB-0000EU-8h for bug-gnu-emacs@gnu.org; Thu, 06 May 2021 17:35:03 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Spencer Baugh Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 06 May 2021 21:35:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 48264 X-GNU-PR-Package: emacs Original-Received: via spool by 48264-submit@debbugs.gnu.org id=B48264.1620336853811 (code B ref 48264); Thu, 06 May 2021 21:35:03 +0000 Original-Received: (at 48264) by debbugs.gnu.org; 6 May 2021 21:34:13 +0000 Original-Received: from localhost ([127.0.0.1]:39879 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1leldM-0000Cv-EA for submit@debbugs.gnu.org; Thu, 06 May 2021 17:34:12 -0400 Original-Received: from venus.catern.com ([68.183.49.163]:41504) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1leldB-0000AJ-Ep for 48264@debbugs.gnu.org; Thu, 06 May 2021 17:34:03 -0400 Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=98.7.229.235; helo=localhost; envelope-from=sbaugh@catern.com; receiver= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=catern.com; s=mail; t=1620336841; bh=dSNJJAepnr9Zuqd+TxBmr4Mvny94ss+YKnXud518MmU=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=E6j7fwr2hVzA6b7euEfzseb+tkzGAsDLmO/4NGOD6ZgVuip49B7oOpf9f65NpmXle uWGH6gxglnwXAsNmiw1EWeiMicLc7nCg2tQ/O/zSuSzuKH3E41xny9n4mjTgC6aBMM /kTaZ03QknMcxErCOVvUIh+QeHjuzCV6gbPtr8+4= Original-Received: from localhost (cpe-98-7-229-235.nyc.res.rr.com [98.7.229.235]) by venus.catern.com (Postfix) with ESMTPSA id 25E0A2E9669; Thu, 6 May 2021 21:34:01 +0000 (UTC) X-Mailer: git-send-email 2.31.1 In-Reply-To: <877dkbsj9d.fsf@catern.com> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:205885 Archived-At: Previously, we used the local_flags array in each struct buffer to know which field was buffer-local. Now, we set the field to Qunbound if it's not buffer-local, and use that to determine if the variable is local. We'll delete local_flags in a followup commit. * src/buffer.h (BVAR_OR_DEFAULT): Update implementation to (bvar_get): Add an offset-based function version of BVAR_OR_DEFAULT. (PER_BUFFER_VALUE_P): Check if value is Qunbound instead of checking local_flags. (KILL_PER_BUFFER_VALUE): Set killed buffer-local vars to Qunbound, not the default value. * src/buffer.c (reset_buffer): Set killed buffer-local vars to Qunbound, not the default value. (buffer_local_value): Use bvar_get so we look up defaults. (init_buffer_once): Don't call reset_buffer_local_variables on pseudobuffers, so we don't set all their values to Qunbound. * src/data.c (do_symval_forwarding): Use bvar_get so we look up defaults. (store_symval_forwarding, set_default_internal): Don't loop all over buffers when setting buffer defaults; this fixes bug#41029. * test/src/data-tests.el (data-tests--set-default-per-buffer): Enable, this is fixed now. --- src/buffer.c | 9 ++------ src/buffer.h | 22 +++++++++++++------ src/data.c | 50 ++---------------------------------------- test/src/data-tests.el | 1 - 4 files changed, 19 insertions(+), 63 deletions(-) diff --git a/src/buffer.c b/src/buffer.c index cc2df67f6c..b9ac93c5e8 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -54,8 +54,7 @@ along with GNU Emacs. If not, see . */ defined with DEFVAR_PER_BUFFER, that have special slots in each buffer. The default value occupies the same slot in this structure as an individual buffer's value occupies in that buffer. - Setting the default value also goes through the alist of buffers - and stores into each buffer that does not say it has a local value. */ +*/ struct buffer buffer_defaults; @@ -989,8 +988,6 @@ reset_buffer (register struct buffer *b) bset_display_count (b, make_fixnum (0)); bset_display_time (b, Qnil); bset_enable_multibyte_characters (b, Qt); - bset_cursor_type (b, BVAR (&buffer_defaults, cursor_type)); - bset_extra_line_spacing (b, BVAR (&buffer_defaults, extra_line_spacing)); b->display_error_modiff = 0; } @@ -1260,7 +1257,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer) { lispfwd fwd = SYMBOL_FWD (sym); if (BUFFER_OBJFWDP (fwd)) - result = per_buffer_value (buf, XBUFFER_OBJFWD (fwd)->offset); + result = bvar_get (buf, XBUFFER_OBJFWD (fwd)->offset); else result = Fdefault_value (variable); break; @@ -5251,10 +5248,8 @@ init_buffer_once (void) are initialized reasonably, so mark_buffer won't choke. */ reset_buffer (&buffer_defaults); eassert (NILP (BVAR (&buffer_defaults, name))); - reset_buffer_local_variables (&buffer_defaults, 1); eassert (NILP (BVAR (&buffer_local_symbols, name))); reset_buffer (&buffer_local_symbols); - reset_buffer_local_variables (&buffer_local_symbols, 1); /* Prevent GC from getting confused. */ buffer_defaults.text = &buffer_defaults.own_text; buffer_local_symbols.text = &buffer_local_symbols.own_text; diff --git a/src/buffer.h b/src/buffer.h index 0af51d3348..ee5924dad8 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -284,7 +284,9 @@ struct buffer_text #define BVAR(buf, field) ((buf)->field ## _) -#define BVAR_OR_DEFAULT(buf, field) BVAR (buf, field) +#define BVAR_OR_DEFAULT(buf, field) (EQ (BVAR ((buf), field), Qunbound) \ + ? BVAR (&buffer_defaults, field) \ + : BVAR ((buf), field)) /* Max number of builtin per-buffer variables. */ enum { MAX_PER_BUFFER_VARS = 50 }; @@ -1107,8 +1109,7 @@ BUFFER_CHECK_INDIRECTION (struct buffer *b) that have special slots in each buffer. The default value occupies the same slot in this structure as an individual buffer's value occupies in that buffer. - Setting the default value also goes through the alist of buffers - and stores into each buffer that does not say it has a local value. */ +*/ extern struct buffer buffer_defaults; @@ -1499,9 +1500,16 @@ BUFFER_DEFAULT_VALUE_P (int offset) INLINE bool PER_BUFFER_VALUE_P (struct buffer *b, int offset) { - int idx = PER_BUFFER_IDX (offset); - eassert (idx == -1 || valid_per_buffer_idx (idx)); - return idx == -1 || b->local_flags[idx]; + return !EQ (per_buffer_value (b, offset), Qunbound); +} + +INLINE Lisp_Object +bvar_get (struct buffer *b, ptrdiff_t offset) +{ + Lisp_Object val = per_buffer_value (b, offset); + return EQ (val, Qunbound) + ? per_buffer_default (offset) + : val; } /* Kill the per-buffer binding for this value, if there is one. */ @@ -1511,7 +1519,7 @@ KILL_PER_BUFFER_VALUE (struct buffer *b, int offset) { int idx = PER_BUFFER_IDX (offset); SET_PER_BUFFER_VALUE_P (b, idx, 0); - set_per_buffer_value (b, offset, per_buffer_default (offset)); + set_per_buffer_value (b, offset, Qunbound); } /* Downcase a character C, or make no change if that cannot be done. */ diff --git a/src/data.c b/src/data.c index b3d3111eaa..04c27b4940 100644 --- a/src/data.c +++ b/src/data.c @@ -1161,8 +1161,8 @@ do_symval_forwarding (lispfwd valcontents) return *XOBJFWD (valcontents)->objvar; case Lisp_Fwd_Buffer_Obj: - return per_buffer_value (current_buffer, - XBUFFER_OBJFWD (valcontents)->offset); + return bvar_get (current_buffer, + XBUFFER_OBJFWD (valcontents)->offset); case Lisp_Fwd_Kboard_Obj: /* We used to simply use current_kboard here, but from Lisp @@ -1259,31 +1259,6 @@ store_symval_forwarding (lispfwd valcontents, Lisp_Object newval, case Lisp_Fwd_Obj: *XOBJFWD (valcontents)->objvar = newval; - - /* If this variable is a default for something stored - in the buffer itself, such as default-fill-column, - find the buffers that don't have local values for it - and update them. */ - if (XOBJFWD (valcontents)->objvar > (Lisp_Object *) &buffer_defaults - && XOBJFWD (valcontents)->objvar < (Lisp_Object *) (&buffer_defaults + 1)) - { - int offset = ((char *) XOBJFWD (valcontents)->objvar - - (char *) &buffer_defaults); - int idx = PER_BUFFER_IDX (offset); - - Lisp_Object tail, buf; - - if (idx <= 0) - break; - - FOR_EACH_LIVE_BUFFER (tail, buf) - { - struct buffer *b = XBUFFER (buf); - - if (! PER_BUFFER_VALUE_P (b, offset)) - set_per_buffer_value (b, offset, newval); - } - } break; case Lisp_Fwd_Buffer_Obj: @@ -1883,27 +1858,6 @@ set_default_internal (Lisp_Object symbol, Lisp_Object value, int offset = XBUFFER_OBJFWD (valcontents)->offset; set_per_buffer_default (offset, value); - - /* If this variable is not always local in all buffers, - set it in the buffers that don't nominally have a local value. */ - if (BUFFER_DEFAULT_VALUE_P (offset)) - { - Lisp_Object buf, tail; - - /* Do this only in live buffers, so that if there are - a lot of buffers which are dead, that doesn't slow - down let-binding of variables that are - automatically local when set, like - case-fold-search. This is for Lisp programs that - let-bind such variables in their inner loops. */ - FOR_EACH_LIVE_BUFFER (tail, buf) - { - struct buffer *b = XBUFFER (buf); - - if (!PER_BUFFER_VALUE_P (b, offset)) - set_per_buffer_value (b, offset, value); - } - } } else set_internal (symbol, value, Qnil, bindflag); diff --git a/test/src/data-tests.el b/test/src/data-tests.el index b1e5fa0767..eae2109fe6 100644 --- a/test/src/data-tests.el +++ b/test/src/data-tests.el @@ -424,7 +424,6 @@ comparing the subr with a much slower lisp implementation." (with-no-warnings (should (setq :keyword :keyword)))) (ert-deftest data-tests--set-default-per-buffer () - :expected-result t ;; Not fixed yet! ;; FIXME: Performance tests are inherently unreliable. ;; Using wall-clock time makes it even worse, so don't bother unless ;; we have the primitive to measure cpu-time. -- 2.31.1