2012-07-24 Paul Eggert * lisp.h (XLI, XIL, CHECK_TYPE, CHECK_LIST_CONS, CHECK_NUMBER) (CHECK_SYMBOL, CONSP, EQ, FLOATP, INTEGERP, LISP_INT_TAG_P, MARKERP) (MISCP, NILP, SET_SYMBOL_VAL, SYMBOL_CONSTANT_P, SYMBOL_VAL, SYMBOLP) (VECTORLIKEP, XCAR, XCDR, XCONS, XHASH, XPNTR, XSYMBOL): If compiling via GCC without optimization, inline these functions manually, by defining macros in addition to inline functions. To disable this, compile with -DINLINING=0. (make_number, XFASTINT, XINT, XTYPE, XUNTAG): Likewise, but hand-optimize only in the USE_LSB_TAG case, as GNUish hosts do that. === modified file 'src/lisp.h' --- src/lisp.h 2012-07-23 21:58:10 +0000 +++ src/lisp.h 2012-07-24 01:57:18 +0000 @@ -214,6 +214,62 @@ #endif +/* When compiling via GCC without optimization, inline a few functions + manually, as Emacs is too slow otherwise. There's no need to + inline everything, just the functions that would cause a serious + performance problem when debugging. To disable this hand-optimization, + compile with -DINLINING=0. + + Commentary for these macros can be found near their corresponding + functions, below. */ +#if (defined __NO_INLINE__ \ + && ! defined __OPTIMIZE__ && ! defined __OPTIMIZE_SIZE__ \ + && ! (defined INLINING && ! INLINING)) +# if CHECK_LISP_OBJECT_TYPE +# define XLI(o) (o).i +# define XIL(i) (Lisp_Object) { i } +# else +# define XLI(o) (o) +# define XIL(i) (i) +# endif +# define CHECK_TYPE(ok, Qxxxp, x) \ + ((void) ((ok) || wrong_type_argument (Qxxxp, x))) +# define CHECK_LIST_CONS(x, y) CHECK_TYPE (CONSP (x), Qlistp, y) +# define CHECK_NUMBER(x) CHECK_TYPE (INTEGERP (x), Qintegerp, x) +# define CHECK_SYMBOL(x) CHECK_TYPE (SYMBOLP (x), Qsymbolp, x) +# define CONSP(x) (XTYPE (x) == Lisp_Cons) +# define EQ(a, b) (XHASH (a) == XHASH (b)) +# define FLOATP(x) (XTYPE (x) == Lisp_Float) +# define INTEGERP(x) LISP_INT_TAG_P (XTYPE (x)) +# define LISP_INT_TAG_P(x) (((x) & ~Lisp_Int1) == 0) +# define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) +# define MISCP(x) (XTYPE (x) == Lisp_Misc) +# define NILP(x) EQ (x, Qnil) +# define SET_SYMBOL_VAL(sym, v) \ + (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value = (v)) +# define SYMBOL_CONSTANT_P(sym) (XSYMBOL (sym)->constant) +# define SYMBOL_VAL(sym) \ + (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value) +# define SYMBOLP(x) (XTYPE (x) == Lisp_Symbol) +# define VECTORLIKEP(x) (XTYPE (x) == Lisp_Vectorlike) +# define XCAR(c) XCAR_AS_LVALUE (c) +# define XCDR(c) XCDR_AS_LVALUE (c) +# define XCONS(a) \ + (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons)) +# define XHASH(o) XLI (o) +# define XPNTR(a) ((void *) (intptr_t) ((XLI (a) & VALMASK) | DATA_SEG_BITS)) +# define XSYMBOL(a) \ + (eassert (SYMBOLP (a)), (struct Lisp_Symbol *) XUNTAG (a, Lisp_Symbol)) +# if USE_LSB_TAG +# define make_number(n) XIL ((EMACS_INT) (n) << INTTYPEBITS) +# define XFASTINT(a) XINT (a) +# define XINT(a) (XLI (a) >> INTTYPEBITS) +# define XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK)) +# define XUNTAG(a, type) ((void *) (XLI (a) - (type))) +# endif +#endif + + /* Define the fundamental Lisp data structures. */ /* This is the set of Lisp data types. */ @@ -266,7 +322,7 @@ /* An older name for Lisp_Int0. */ enum { LISP_INT_TAG = Lisp_Int0 }; -static inline int LISP_INT_TAG_P (int x) { return (x & ~Lisp_Int1) == 0; } +static inline int (LISP_INT_TAG_P) (int x) { return (x & ~Lisp_Int1) == 0; } /* This is the set of data types that share a common structure. The first member of the structure is a type code from this set. @@ -302,10 +358,10 @@ typedef struct { EMACS_INT i; } Lisp_Object; -static inline EMACS_INT XLI (Lisp_Object o) { return o.i; } +static inline EMACS_INT (XLI) (Lisp_Object o) { return o.i; } static inline Lisp_Object -XIL (EMACS_INT i) +(XIL) (EMACS_INT i) { Lisp_Object o = { i }; return o; @@ -318,8 +374,8 @@ /* If a struct type is not wanted, define Lisp_Object as just a number. */ typedef EMACS_INT Lisp_Object; -static inline EMACS_INT XLI (Lisp_Object o) { return o; } -static inline Lisp_Object XIL (EMACS_INT i) { return i; } +static inline EMACS_INT (XLI) (Lisp_Object o) { return o; } +static inline Lisp_Object (XIL) (EMACS_INT i) { return i; } #define LISP_INITIALLY_ZERO 0 #endif /* CHECK_LISP_OBJECT_TYPE */ @@ -389,7 +445,7 @@ XCONS (tem) is the struct Lisp_Cons * pointing to the memory for that cons. */ /* Return a perfect hash of the Lisp_Object representation. */ -static inline EMACS_INT XHASH (Lisp_Object o) { return XLI (o); } +static inline EMACS_INT (XHASH) (Lisp_Object o) { return XLI (o); } #define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX) @@ -399,7 +455,7 @@ #define MOST_NEGATIVE_FIXNUM (-1 - MOST_POSITIVE_FIXNUM) static inline enum Lisp_Type -XTYPE (Lisp_Object a) +(XTYPE) (Lisp_Object a) { EMACS_UINT i = XLI (a); return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS; @@ -407,7 +463,7 @@ /* Extract the value of a Lisp_Object as a signed integer. */ static inline EMACS_INT -XINT (Lisp_Object a) +(XINT) (Lisp_Object a) { EMACS_INT i = XLI (a); return (USE_LSB_TAG ? i : i << INTTYPEBITS) >> INTTYPEBITS; @@ -416,7 +472,7 @@ /* Like XINT (A), but may be faster. A must be nonnegative. This takes advantage of the fact that Lisp integers have zero-bits in their tags. */ static inline EMACS_INT -XFASTINT (Lisp_Object a) +(XFASTINT) (Lisp_Object a) { EMACS_INT n = USE_LSB_TAG ? XINT (a) : XLI (a) >> INTTYPEBITS; eassert (0 <= n); @@ -432,7 +488,7 @@ } static inline Lisp_Object -make_number (EMACS_INT n) +(make_number) (EMACS_INT n) { return XIL (USE_LSB_TAG ? n << INTTYPEBITS : n & INTMASK); } @@ -446,7 +502,7 @@ } static inline void * -XPNTR (Lisp_Object a) +(XPNTR) (Lisp_Object a) { intptr_t i = (XLI (a) & VALMASK) | DATA_SEG_BITS; return (void *) i; @@ -455,7 +511,7 @@ /* Extract the pointer value of the Lisp object A, under the assumption that A's type is TYPE. */ static inline void * -XUNTAG (Lisp_Object a, int type) +(XUNTAG) (Lisp_Object a, int type) { if (USE_LSB_TAG) { @@ -466,7 +522,7 @@ } static inline int -EQ (Lisp_Object a, Lisp_Object b) +(EQ) (Lisp_Object a, Lisp_Object b) { return XHASH (a) == XHASH (b); } @@ -503,14 +559,14 @@ static int BUFFERP (Lisp_Object); static int CHAR_TABLE_P (Lisp_Object); static Lisp_Object CHAR_TABLE_REF_ASCII (Lisp_Object, ptrdiff_t); -static int CONSP (Lisp_Object); -static int FLOATP (Lisp_Object); -static int INTEGERP (Lisp_Object); +static int (CONSP) (Lisp_Object); +static int (FLOATP) (Lisp_Object); +static int (INTEGERP) (Lisp_Object); static int INTFWDP (union Lisp_Fwd *); static int KBOARD_OBJFWDP (union Lisp_Fwd *); -static int MARKERP (Lisp_Object); -static int MISCP (Lisp_Object); -static int NILP (Lisp_Object); +static int (MARKERP) (Lisp_Object); +static int (MISCP) (Lisp_Object); +static int (NILP) (Lisp_Object); static int OBJFWDP (union Lisp_Fwd *); static int OVERLAYP (Lisp_Object); static int PROCESSP (Lisp_Object); @@ -519,8 +575,8 @@ static int STRINGP (Lisp_Object); static int SUB_CHAR_TABLE_P (Lisp_Object); static int SUBRP (Lisp_Object); -static int SYMBOLP (Lisp_Object); -static int VECTORLIKEP (Lisp_Object); +static int (SYMBOLP) (Lisp_Object); +static int (VECTORLIKEP) (Lisp_Object); static int WINDOWP (Lisp_Object); /* Defined in buffer.c. */ @@ -561,7 +617,7 @@ /* Extract a value or address from a Lisp_Object. */ static inline struct Lisp_Cons * -XCONS (Lisp_Object a) +(XCONS) (Lisp_Object a) { eassert (CONSP (a)); return XUNTAG (a, Lisp_Cons); @@ -582,7 +638,7 @@ } static inline struct Lisp_Symbol * -XSYMBOL (Lisp_Object a) +(XSYMBOL) (Lisp_Object a) { eassert (SYMBOLP (a)); return XUNTAG (a, Lisp_Symbol); @@ -717,7 +773,7 @@ /* Type checking. */ static inline void -CHECK_TYPE (int ok, Lisp_Object Qxxxp, Lisp_Object x) +(CHECK_TYPE) (int ok, Lisp_Object Qxxxp, Lisp_Object x) { if (!ok) wrong_type_argument (Qxxxp, x); @@ -773,8 +829,8 @@ #endif /* Use these from normal code. */ -static inline Lisp_Object XCAR (Lisp_Object c) { return XCAR_AS_LVALUE (c); } -static inline Lisp_Object XCDR (Lisp_Object c) { return XCDR_AS_LVALUE (c); } +static inline Lisp_Object (XCAR) (Lisp_Object c) { return XCAR_AS_LVALUE (c); } +static inline Lisp_Object (XCDR) (Lisp_Object c) { return XCDR_AS_LVALUE (c); } /* Use these to set the fields of a cons cell. @@ -1276,7 +1332,7 @@ /* Value is name of symbol. */ static inline Lisp_Object -SYMBOL_VAL (struct Lisp_Symbol *sym) +(SYMBOL_VAL) (struct Lisp_Symbol *sym) { eassert (sym->redirect == SYMBOL_PLAINVAL); return sym->val.value; @@ -1300,7 +1356,7 @@ return sym->val.fwd; } static inline void -SET_SYMBOL_VAL (struct Lisp_Symbol *sym, Lisp_Object v) +(SET_SYMBOL_VAL) (struct Lisp_Symbol *sym, Lisp_Object v) { eassert (sym->redirect == SYMBOL_PLAINVAL); sym->val.value = v; @@ -1351,7 +1407,7 @@ whose value can be set to the keyword symbol itself). */ static inline int -SYMBOL_CONSTANT_P (Lisp_Object sym) +(SYMBOL_CONSTANT_P) (Lisp_Object sym) { return XSYMBOL (sym)->constant; } @@ -1915,7 +1971,7 @@ /* Data type checking */ static inline int -NILP (Lisp_Object x) +(NILP) (Lisp_Object x) { return EQ (x, Qnil); } @@ -1942,18 +1998,22 @@ && (TYPE_SIGNED (type) ? TYPE_MINIMUM (type) <= XINT (x) : 0 <= XINT (x)) \ && XINT (x) <= TYPE_MAXIMUM (type)) -static inline int CONSP (Lisp_Object x) { return XTYPE (x) == Lisp_Cons; } -static inline int FLOATP (Lisp_Object x) { return XTYPE (x) == Lisp_Float; } -static inline int MISCP (Lisp_Object x) { return XTYPE (x) == Lisp_Misc; } +static inline int (CONSP) (Lisp_Object x) { return XTYPE (x) == Lisp_Cons; } +static inline int (FLOATP) (Lisp_Object x) { return XTYPE (x) == Lisp_Float; } +static inline int (MISCP) (Lisp_Object x) { return XTYPE (x) == Lisp_Misc; } static inline int STRINGP (Lisp_Object x) { return XTYPE (x) == Lisp_String; } -static inline int SYMBOLP (Lisp_Object x) { return XTYPE (x) == Lisp_Symbol; } -static inline int -INTEGERP (Lisp_Object x) +static inline int +(SYMBOLP) (Lisp_Object x) +{ + return XTYPE (x) == Lisp_Symbol; +} +static inline int +(INTEGERP) (Lisp_Object x) { return LISP_INT_TAG_P (XTYPE (x)); } static inline int -VECTORLIKEP (Lisp_Object x) +(VECTORLIKEP) (Lisp_Object x) { return XTYPE (x) == Lisp_Vectorlike; } @@ -1968,7 +2028,7 @@ return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Overlay; } static inline int -MARKERP (Lisp_Object x) +(MARKERP) (Lisp_Object x) { return MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker; } @@ -2123,7 +2183,7 @@ CHECK_TYPE (CONSP (x) || NILP (x), Qlistp, x); } static inline void -CHECK_LIST_CONS (Lisp_Object x, Lisp_Object y) +(CHECK_LIST_CONS) (Lisp_Object x, Lisp_Object y) { CHECK_TYPE (CONSP (x), Qlistp, y); } @@ -2148,7 +2208,7 @@ CHECK_TYPE (CONSP (x), Qconsp, x); } static inline void -CHECK_SYMBOL (Lisp_Object x) +(CHECK_SYMBOL) (Lisp_Object x) { CHECK_TYPE (SYMBOLP (x), Qsymbolp, x); } @@ -2203,7 +2263,7 @@ CHECK_TYPE (SUBRP (x), Qsubrp, x); } static inline void -CHECK_NUMBER (Lisp_Object x) +(CHECK_NUMBER) (Lisp_Object x) { CHECK_TYPE (INTEGERP (x), Qintegerp, x); }