summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2015-12-12 19:27:51 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2015-12-12 19:28:53 -0800
commit09663d9b91803882508bd805581b95f8990eb441 (patch)
treea42fd5bacc97e94c2f60ee801cdc908b15b2df9a /src
parent95a5c23f741f42c6f68e283570cdce10b1946296 (diff)
downloademacs-09663d9b91803882508bd805581b95f8990eb441.tar.gz
Fix performance regression with gcc -O0
This fixes the smaller performance hit that I noted in: https://lists.gnu.org/archive/html/emacs-devel/2015-12/msg00357.html * src/alloc.c (macro_XPNTR_OR_SYMBOL_OFFSET, macro_XPNTR): * src/puresize.h (puresize_h_PURE_P) (puresize_h_CHECK_IMPURE): New macros, with the old contents of the functions. * src/alloc.c (XPNTR_OR_SYMBOL_OFFSET, XPNTR): * src/puresize.h (PURE_P, CHECK_IMPURE): Use the new macros. Also macros, if DEFINE_KEY_OPS_AS_MACROS. * src/conf_post.h (ATTRIBUTE_UNUSED): * src/lisp.h (DEFINE_KEY_OPS_AS_MACROS): New macros.
Diffstat (limited to 'src')
-rw-r--r--src/alloc.c35
-rw-r--r--src/conf_post.h1
-rw-r--r--src/lisp.h6
-rw-r--r--src/puresize.h20
4 files changed, 48 insertions, 14 deletions
diff --git a/src/alloc.c b/src/alloc.c
index ea44c51d162..23ddd83d7d6 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -406,24 +406,37 @@ ALIGN (void *ptr, int alignment)
If A is a symbol, extract the hidden pointer's offset from lispsym,
converted to void *. */
-static void *
-XPNTR_OR_SYMBOL_OFFSET (Lisp_Object a)
-{
- intptr_t i = USE_LSB_TAG ? XLI (a) - XTYPE (a) : XLI (a) & VALMASK;
- return (void *) i;
-}
+#define macro_XPNTR_OR_SYMBOL_OFFSET(a) \
+ ((void *) (intptr_t) (USE_LSB_TAG ? XLI (a) - XTYPE (a) : XLI (a) & VALMASK))
/* Extract the pointer hidden within A. */
-static void *
+#define macro_XPNTR(a) \
+ ((void *) ((intptr_t) XPNTR_OR_SYMBOL_OFFSET (a) \
+ + (SYMBOLP (a) ? (char *) lispsym : NULL)))
+
+/* For pointer access, define XPNTR and XPNTR_OR_SYMBOL_OFFSET as
+ functions, as functions are cleaner and can be used in debuggers.
+ Also, define them as macros if being compiled with GCC without
+ optimization, for performance in that case. The macro_* names are
+ private to this section of code. */
+
+static ATTRIBUTE_UNUSED void *
+XPNTR_OR_SYMBOL_OFFSET (Lisp_Object a)
+{
+ return macro_XPNTR_OR_SYMBOL_OFFSET (a);
+}
+static ATTRIBUTE_UNUSED void *
XPNTR (Lisp_Object a)
{
- void *p = XPNTR_OR_SYMBOL_OFFSET (a);
- if (SYMBOLP (a))
- p = (intptr_t) p + (char *) lispsym;
- return p;
+ return macro_XPNTR (a);
}
+#if DEFINE_KEY_OPS_AS_MACROS
+# define XPNTR_OR_SYMBOL_OFFSET(a) macro_XPNTR_OR_SYMBOL_OFFSET (a)
+# define XPNTR(a) macro_XPNTR (a)
+#endif
+
static void
XFLOAT_INIT (Lisp_Object f, double n)
{
diff --git a/src/conf_post.h b/src/conf_post.h
index 2c3eee59b77..b629e8d3df7 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -245,6 +245,7 @@ extern int emacs_setenv_TZ (char const *);
#endif
#define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST
+#define ATTRIBUTE_UNUSED _GL_UNUSED
#if 3 <= __GNUC__
# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
diff --git a/src/lisp.h b/src/lisp.h
index ee9b7b62bf4..995760a5019 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -369,6 +369,12 @@ error !;
#if (defined __NO_INLINE__ \
&& ! defined __OPTIMIZE__ && ! defined __OPTIMIZE_SIZE__ \
&& ! (defined INLINING && ! INLINING))
+# define DEFINE_KEY_OPS_AS_MACROS true
+#else
+# define DEFINE_KEY_OPS_AS_MACROS false
+#endif
+
+#if DEFINE_KEY_OPS_AS_MACROS
# define XLI(o) lisp_h_XLI (o)
# define XIL(i) lisp_h_XIL (i)
# define CHECK_LIST_CONS(x, y) lisp_h_CHECK_LIST_CONS (x, y)
diff --git a/src/puresize.h b/src/puresize.h
index f07562429d5..96ddcde24a6 100644
--- a/src/puresize.h
+++ b/src/puresize.h
@@ -81,21 +81,35 @@ extern _Noreturn void pure_write_error (Lisp_Object);
extern EMACS_INT pure[];
+/* The puresize_h_* macros are private to this include file. */
+
/* True if PTR is pure. */
+
+#define puresize_h_PURE_P(ptr) \
+ ((uintptr_t) (ptr) - (uintptr_t) pure <= PURESIZE)
+
INLINE bool
PURE_P (void *ptr)
{
- return (uintptr_t) (ptr) - (uintptr_t) pure <= PURESIZE;
+ return puresize_h_PURE_P (ptr);
}
/* Signal an error if OBJ is pure. PTR is OBJ untagged. */
+
+#define puresize_h_CHECK_IMPURE(obj, ptr) \
+ (PURE_P (ptr) ? pure_write_error (obj) : (void) 0)
+
INLINE void
CHECK_IMPURE (Lisp_Object obj, void *ptr)
{
- if (PURE_P (ptr))
- pure_write_error (obj);
+ puresize_h_CHECK_IMPURE (obj, ptr);
}
+#if DEFINE_KEY_OPS_AS_MACROS
+# define PURE_P(ptr) puresize_h_PURE_P (ptr)
+# define CHECK_IMPURE(obj, ptr) puresize_h_CHECK_IMPURE (obj, ptr)
+#endif
+
INLINE_HEADER_END
#endif /* EMACS_PURESIZE_H */