From 09663d9b91803882508bd805581b95f8990eb441 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 12 Dec 2015 19:27:51 -0800 Subject: [PATCH] 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. --- src/alloc.c | 35 ++++++++++++++++++++++++----------- src/conf_post.h | 1 + src/lisp.h | 6 ++++++ src/puresize.h | 20 +++++++++++++++++--- 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 */ -- 2.39.2