diff options
| author | Paul Eggert | 2015-12-12 19:27:51 -0800 |
|---|---|---|
| committer | Paul Eggert | 2015-12-12 19:28:53 -0800 |
| commit | 09663d9b91803882508bd805581b95f8990eb441 (patch) | |
| tree | a42fd5bacc97e94c2f60ee801cdc908b15b2df9a /src | |
| parent | 95a5c23f741f42c6f68e283570cdce10b1946296 (diff) | |
| download | emacs-09663d9b91803882508bd805581b95f8990eb441.tar.gz emacs-09663d9b91803882508bd805581b95f8990eb441.zip | |
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.c | 35 | ||||
| -rw-r--r-- | src/conf_post.h | 1 | ||||
| -rw-r--r-- | src/lisp.h | 6 | ||||
| -rw-r--r-- | 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) | |||
| 406 | If A is a symbol, extract the hidden pointer's offset from lispsym, | 406 | If A is a symbol, extract the hidden pointer's offset from lispsym, |
| 407 | converted to void *. */ | 407 | converted to void *. */ |
| 408 | 408 | ||
| 409 | static void * | 409 | #define macro_XPNTR_OR_SYMBOL_OFFSET(a) \ |
| 410 | XPNTR_OR_SYMBOL_OFFSET (Lisp_Object a) | 410 | ((void *) (intptr_t) (USE_LSB_TAG ? XLI (a) - XTYPE (a) : XLI (a) & VALMASK)) |
| 411 | { | ||
| 412 | intptr_t i = USE_LSB_TAG ? XLI (a) - XTYPE (a) : XLI (a) & VALMASK; | ||
| 413 | return (void *) i; | ||
| 414 | } | ||
| 415 | 411 | ||
| 416 | /* Extract the pointer hidden within A. */ | 412 | /* Extract the pointer hidden within A. */ |
| 417 | 413 | ||
| 418 | static void * | 414 | #define macro_XPNTR(a) \ |
| 415 | ((void *) ((intptr_t) XPNTR_OR_SYMBOL_OFFSET (a) \ | ||
| 416 | + (SYMBOLP (a) ? (char *) lispsym : NULL))) | ||
| 417 | |||
| 418 | /* For pointer access, define XPNTR and XPNTR_OR_SYMBOL_OFFSET as | ||
| 419 | functions, as functions are cleaner and can be used in debuggers. | ||
| 420 | Also, define them as macros if being compiled with GCC without | ||
| 421 | optimization, for performance in that case. The macro_* names are | ||
| 422 | private to this section of code. */ | ||
| 423 | |||
| 424 | static ATTRIBUTE_UNUSED void * | ||
| 425 | XPNTR_OR_SYMBOL_OFFSET (Lisp_Object a) | ||
| 426 | { | ||
| 427 | return macro_XPNTR_OR_SYMBOL_OFFSET (a); | ||
| 428 | } | ||
| 429 | static ATTRIBUTE_UNUSED void * | ||
| 419 | XPNTR (Lisp_Object a) | 430 | XPNTR (Lisp_Object a) |
| 420 | { | 431 | { |
| 421 | void *p = XPNTR_OR_SYMBOL_OFFSET (a); | 432 | return macro_XPNTR (a); |
| 422 | if (SYMBOLP (a)) | ||
| 423 | p = (intptr_t) p + (char *) lispsym; | ||
| 424 | return p; | ||
| 425 | } | 433 | } |
| 426 | 434 | ||
| 435 | #if DEFINE_KEY_OPS_AS_MACROS | ||
| 436 | # define XPNTR_OR_SYMBOL_OFFSET(a) macro_XPNTR_OR_SYMBOL_OFFSET (a) | ||
| 437 | # define XPNTR(a) macro_XPNTR (a) | ||
| 438 | #endif | ||
| 439 | |||
| 427 | static void | 440 | static void |
| 428 | XFLOAT_INIT (Lisp_Object f, double n) | 441 | XFLOAT_INIT (Lisp_Object f, double n) |
| 429 | { | 442 | { |
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 *); | |||
| 245 | #endif | 245 | #endif |
| 246 | 246 | ||
| 247 | #define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST | 247 | #define ATTRIBUTE_CONST _GL_ATTRIBUTE_CONST |
| 248 | #define ATTRIBUTE_UNUSED _GL_UNUSED | ||
| 248 | 249 | ||
| 249 | #if 3 <= __GNUC__ | 250 | #if 3 <= __GNUC__ |
| 250 | # define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) | 251 | # 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 !; | |||
| 369 | #if (defined __NO_INLINE__ \ | 369 | #if (defined __NO_INLINE__ \ |
| 370 | && ! defined __OPTIMIZE__ && ! defined __OPTIMIZE_SIZE__ \ | 370 | && ! defined __OPTIMIZE__ && ! defined __OPTIMIZE_SIZE__ \ |
| 371 | && ! (defined INLINING && ! INLINING)) | 371 | && ! (defined INLINING && ! INLINING)) |
| 372 | # define DEFINE_KEY_OPS_AS_MACROS true | ||
| 373 | #else | ||
| 374 | # define DEFINE_KEY_OPS_AS_MACROS false | ||
| 375 | #endif | ||
| 376 | |||
| 377 | #if DEFINE_KEY_OPS_AS_MACROS | ||
| 372 | # define XLI(o) lisp_h_XLI (o) | 378 | # define XLI(o) lisp_h_XLI (o) |
| 373 | # define XIL(i) lisp_h_XIL (i) | 379 | # define XIL(i) lisp_h_XIL (i) |
| 374 | # define CHECK_LIST_CONS(x, y) lisp_h_CHECK_LIST_CONS (x, y) | 380 | # 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); | |||
| 81 | 81 | ||
| 82 | extern EMACS_INT pure[]; | 82 | extern EMACS_INT pure[]; |
| 83 | 83 | ||
| 84 | /* The puresize_h_* macros are private to this include file. */ | ||
| 85 | |||
| 84 | /* True if PTR is pure. */ | 86 | /* True if PTR is pure. */ |
| 87 | |||
| 88 | #define puresize_h_PURE_P(ptr) \ | ||
| 89 | ((uintptr_t) (ptr) - (uintptr_t) pure <= PURESIZE) | ||
| 90 | |||
| 85 | INLINE bool | 91 | INLINE bool |
| 86 | PURE_P (void *ptr) | 92 | PURE_P (void *ptr) |
| 87 | { | 93 | { |
| 88 | return (uintptr_t) (ptr) - (uintptr_t) pure <= PURESIZE; | 94 | return puresize_h_PURE_P (ptr); |
| 89 | } | 95 | } |
| 90 | 96 | ||
| 91 | /* Signal an error if OBJ is pure. PTR is OBJ untagged. */ | 97 | /* Signal an error if OBJ is pure. PTR is OBJ untagged. */ |
| 98 | |||
| 99 | #define puresize_h_CHECK_IMPURE(obj, ptr) \ | ||
| 100 | (PURE_P (ptr) ? pure_write_error (obj) : (void) 0) | ||
| 101 | |||
| 92 | INLINE void | 102 | INLINE void |
| 93 | CHECK_IMPURE (Lisp_Object obj, void *ptr) | 103 | CHECK_IMPURE (Lisp_Object obj, void *ptr) |
| 94 | { | 104 | { |
| 95 | if (PURE_P (ptr)) | 105 | puresize_h_CHECK_IMPURE (obj, ptr); |
| 96 | pure_write_error (obj); | ||
| 97 | } | 106 | } |
| 98 | 107 | ||
| 108 | #if DEFINE_KEY_OPS_AS_MACROS | ||
| 109 | # define PURE_P(ptr) puresize_h_PURE_P (ptr) | ||
| 110 | # define CHECK_IMPURE(obj, ptr) puresize_h_CHECK_IMPURE (obj, ptr) | ||
| 111 | #endif | ||
| 112 | |||
| 99 | INLINE_HEADER_END | 113 | INLINE_HEADER_END |
| 100 | 114 | ||
| 101 | #endif /* EMACS_PURESIZE_H */ | 115 | #endif /* EMACS_PURESIZE_H */ |