From: Paul Eggert <eggert@cs.ucla.edu>
To: Philipp Stephani <p.stephani2@gmail.com>
Cc: Emacs developers <emacs-devel@gnu.org>
Subject: Re: Enabling --enable-check-lisp-object-type by default on x86 and AMD64
Date: Tue, 2 May 2017 15:14:17 -0700 [thread overview]
Message-ID: <60379b71-bd6a-5f6f-dec1-523d6f4b2016@cs.ucla.edu> (raw)
In-Reply-To: <CAArVCkQtjkmsBuGmAoeO=ztjOftQUUS-iGRDZCPEJq6WnoOBUg@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1426 bytes --]
Originally, the Lisp_Object type was a struct containing bitfields. This
was significantly slower than using integer shifting and masking on many
platforms, so long ago the default Lisp_Object type was changed to be an
integer. Nowadays Lisp_Object no longer contains bitfields even when
--enable-check-lisp-object-type is used, so this old motivation is no
longer relevant.
For x86-64 there should be little difference nowadays when
--enable-check-lisp-object-type is used. For other platforms (e.g.,
x86), however, I suppose there can still be a significant (though small)
difference. So when compiling emacs for production, it makes sense to
omit --enable-check-lisp-object-type, for the benefit of x86 and similar
platforms.
When developing, the advantages of --enable-check-lisp-object-type
outweigh the small increase in runtime cost, particularly considering
that x86-64 is the most common development platform nowadays and there
the runtime cost is insignificant. So it makes sense to default
--enable-check-lisp-object-type to "yes" if --enable-gcc-warnings is
also enabled (which it is by default, in developer builds). I did this
by installing the attached patch; comments welcome.
As a result, if you build master from a developer (Git-based) directory,
--enable-check-lisp-object-type should now be the default. If you don't
build from Git, I suggest configuring with --enable-gcc-warnings.
[-- Attachment #2: 0001-Check-list-object-type-if-enable-gcc-warnings.txt --]
[-- Type: text/plain, Size: 8434 bytes --]
From f1550f70a1e139022e6238c3c5c22cb7bd6923a1 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Tue, 2 May 2017 14:52:21 -0700
Subject: [PATCH] Check list object type if --enable-gcc-warnings
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* configure.ac (--enable-check-lisp-object-type):
Default to "yes" if --enable-gcc-warnings is not "no".
* etc/NEWS: Mention this.
* src/eval.c (internal_lisp_condition_case): Fix some glitches
with 'volatile' uncovered by the above: in particular, 'clauses'
should be a pointer to volatile storage on the stack, and need not
be volatile itself. Use an int, not ptrdiff_t, to count clauses.
Don’t bother gathering binding count if VAR is nil. Use
more-specific local names to try to clarify what’s going on.
---
configure.ac | 25 +++++++-------
etc/NEWS | 5 ++-
src/eval.c | 105 ++++++++++++++++++++++++++++++-----------------------------
3 files changed, 69 insertions(+), 66 deletions(-)
diff --git a/configure.ac b/configure.ac
index 45cfdfc..d6b8001 100644
--- a/configure.ac
+++ b/configure.ac
@@ -507,16 +507,6 @@ AC_DEFUN
[Define this to enable glyphs debugging code.])
fi
-AC_ARG_ENABLE(check-lisp-object-type,
-[AS_HELP_STRING([--enable-check-lisp-object-type],
- [enable compile time checks for the Lisp_Object data type.
- This is useful for development for catching certain types of bugs.])],
-if test "${enableval}" != "no"; then
- AC_DEFINE(CHECK_LISP_OBJECT_TYPE, 1,
- [Define this to enable compile time checks for the Lisp_Object data type.])
-fi)
-
-
dnl The name of this option is unfortunate. It predates, and has no
dnl relation to, the "sampling-based elisp profiler" added in 24.3.
dnl Actually, it stops it working.
@@ -877,9 +867,18 @@ AC_DEFUN
# just a release imported into Git for patch management.
gl_gcc_warnings=no
if test -e "$srcdir"/.git && test ! -f "$srcdir"/.tarball-version; then
- gl_GCC_VERSION_IFELSE([5], [3], [gl_gcc_warnings=warn-only])]
- fi
-)
+ gl_GCC_VERSION_IFELSE([5], [3], [gl_gcc_warnings=warn-only])
+ fi])
+
+AC_ARG_ENABLE([check-lisp-object-type],
+ [AS_HELP_STRING([--enable-check-lisp-object-type],
+ [Enable compile-time checks for the Lisp_Object data type,
+ which can catch some bugs during development.
+ The default is "no" if --enable-gcc-warnings is "no".])])
+if test "${enable_check_lisp_object_type-$gl_gcc_warnings}" != "no"; then
+ AC_DEFINE([CHECK_LISP_OBJECT_TYPE], 1,
+ [Define to enable compile-time checks for the Lisp_Object data type.])
+fi
# clang is unduly picky about some things.
AC_CACHE_CHECK([whether the compiler is clang], [emacs_cv_clang],
diff --git a/etc/NEWS b/etc/NEWS
index 173c4e4..410e681 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -42,6 +42,9 @@ now the default in developer builds. As before, use
'--disable-gcc-warnings' to suppress GCC's warnings, and
'--enable-gcc-warnings' to stop the build if GCC issues warnings.
+** When GCC warnings are enabled, '--enable-check-lisp-object-type' is
+now enabled by default when configuring.
+
+++
** The Emacs server now has socket-launching support. This allows
socket based activation, where an external process like systemd can
@@ -393,7 +396,7 @@ procedure and therefore obeys saving hooks.
* Changes in Specialized Modes and Packages in Emacs 26.1
*** Info menu and index completion uses substring completion by default.
-This can be customized via the `info-menu` category in
+This can be customized via the info-menu category in
completion-category-override.
+++
diff --git a/src/eval.c b/src/eval.c
index af0912f..0030271 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1225,18 +1225,17 @@ usage: (condition-case VAR BODYFORM &rest HANDLERS) */)
rather than passed in a list. Used by Fbyte_code. */
Lisp_Object
-internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
+internal_lisp_condition_case (Lisp_Object var, Lisp_Object bodyform,
Lisp_Object handlers)
{
- Lisp_Object val;
struct handler *oldhandlerlist = handlerlist;
- int clausenb = 0;
+ ptrdiff_t clausenb = 0;
CHECK_SYMBOL (var);
- for (val = handlers; CONSP (val); val = XCDR (val))
+ for (Lisp_Object tail = handlers; CONSP (tail); tail = XCDR (tail))
{
- Lisp_Object tem = XCAR (val);
+ Lisp_Object tem = XCAR (tail);
clausenb++;
if (! (NILP (tem)
|| (CONSP (tem)
@@ -1246,55 +1245,57 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
SDATA (Fprin1_to_string (tem, Qt)));
}
- { /* The first clause is the one that should be checked first, so it should
- be added to handlerlist last. So we build in `clauses' a table that
- contains `handlers' but in reverse order. SAFE_ALLOCA won't work
- here due to the setjmp, so impose a MAX_ALLOCA limit. */
- if (MAX_ALLOCA / word_size < clausenb)
- memory_full (SIZE_MAX);
- Lisp_Object *clauses = alloca (clausenb * sizeof *clauses);
- Lisp_Object *volatile clauses_volatile = clauses;
- int i = clausenb;
- for (val = handlers; CONSP (val); val = XCDR (val))
- clauses[--i] = XCAR (val);
- for (i = 0; i < clausenb; i++)
- {
- Lisp_Object clause = clauses[i];
- Lisp_Object condition = CONSP (clause) ? XCAR (clause) : Qnil;
- if (!CONSP (condition))
- condition = Fcons (condition, Qnil);
- struct handler *c = push_handler (condition, CONDITION_CASE);
- if (sys_setjmp (c->jmp))
- {
- ptrdiff_t count = SPECPDL_INDEX ();
- Lisp_Object val = handlerlist->val;
- Lisp_Object *chosen_clause = clauses_volatile;
- for (c = handlerlist->next; c != oldhandlerlist; c = c->next)
- chosen_clause++;
- handlerlist = oldhandlerlist;
- if (!NILP (var))
- {
- if (!NILP (Vinternal_interpreter_environment))
- specbind (Qinternal_interpreter_environment,
- Fcons (Fcons (var, val),
- Vinternal_interpreter_environment));
- else
- specbind (var, val);
- }
- val = Fprogn (XCDR (*chosen_clause));
- /* Note that this just undoes the binding of var; whoever
- longjumped to us unwound the stack to c.pdlcount before
- throwing. */
- if (!NILP (var))
- unbind_to (count, Qnil);
- return val;
- }
- }
- }
+ /* The first clause is the one that should be checked first, so it
+ should be added to handlerlist last. So build in CLAUSES a table
+ that contains HANDLERS but in reverse order. CLAUSES is pointer
+ to volatile to avoid issues with setjmp and local storage.
+ SAFE_ALLOCA won't work here due to the setjmp, so impose a
+ MAX_ALLOCA limit. */
+ if (MAX_ALLOCA / word_size < clausenb)
+ memory_full (SIZE_MAX);
+ Lisp_Object volatile *clauses = alloca (clausenb * sizeof *clauses);
+ clauses += clausenb;
+ for (Lisp_Object tail = handlers; CONSP (tail); tail = XCDR (tail))
+ *--clauses = XCAR (tail);
+ for (ptrdiff_t i = 0; i < clausenb; i++)
+ {
+ Lisp_Object clause = clauses[i];
+ Lisp_Object condition = CONSP (clause) ? XCAR (clause) : Qnil;
+ if (!CONSP (condition))
+ condition = list1 (condition);
+ struct handler *c = push_handler (condition, CONDITION_CASE);
+ if (sys_setjmp (c->jmp))
+ {
+ Lisp_Object val = handlerlist->val;
+ Lisp_Object volatile *chosen_clause = clauses;
+ for (struct handler *h = handlerlist->next; h != oldhandlerlist;
+ h = h->next)
+ chosen_clause++;
+ Lisp_Object handler_body = XCDR (*chosen_clause);
+ handlerlist = oldhandlerlist;
+
+ if (NILP (var))
+ return Fprogn (handler_body);
+
+ if (!NILP (Vinternal_interpreter_environment))
+ {
+ val = Fcons (Fcons (var, val),
+ Vinternal_interpreter_environment);
+ var = Qinternal_interpreter_environment;
+ }
+
+ /* Bind VAR to VAL while evaluating HANDLER_BODY. The
+ unbind_to just undoes VAR's binding; whoever longjumped
+ to us unwound the stack to C->pdlcount before throwing. */
+ ptrdiff_t count = SPECPDL_INDEX ();
+ specbind (var, val);
+ return unbind_to (count, Fprogn (handler_body));
+ }
+ }
- val = eval_sub (bodyform);
+ Lisp_Object result = eval_sub (bodyform);
handlerlist = oldhandlerlist;
- return val;
+ return result;
}
/* Call the function BFUN with no arguments, catching errors within it
--
2.9.3
next prev parent reply other threads:[~2017-05-02 22:14 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <m2shl134rd.fsf@gmail.com>
[not found] ` <83mvb8riq0.fsf@gnu.org>
[not found] ` <CAArVCkQoeBwHspkUUih_9EdwnBQ5HWaYHD87Rcyduc8DsooXRg@mail.gmail.com>
[not found] ` <83a878r2d0.fsf@gnu.org>
2017-05-01 11:32 ` Enabling --enable-check-lisp-object-type by default on x86 and AMD64 (was: Re: bug#26597: 25.1; Compilation error on master with --enable-check-lisp-object-type) Philipp Stephani
2017-05-02 22:14 ` Paul Eggert [this message]
2017-05-03 2:38 ` Enabling --enable-check-lisp-object-type by default on x86 and AMD64 Eli Zaretskii
2017-05-03 3:24 ` Paul Eggert
2017-05-03 14:48 ` Eli Zaretskii
2017-05-03 18:08 ` Paul Eggert
2017-05-03 18:22 ` Eli Zaretskii
2017-05-04 14:33 ` Eli Zaretskii
2017-05-05 23:23 ` Paul Eggert
2017-05-06 7:07 ` Eli Zaretskii
2017-05-06 23:23 ` Paul Eggert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=60379b71-bd6a-5f6f-dec1-523d6f4b2016@cs.ucla.edu \
--to=eggert@cs.ucla.edu \
--cc=emacs-devel@gnu.org \
--cc=p.stephani2@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).