From: Paul Eggert <eggert@cs.ucla.edu>
To: Stefan Monnier <monnier@IRO.UMontreal.CA>
Cc: 11935@debbugs.gnu.org
Subject: bug#11935: XINT etc. should be functions
Date: Tue, 24 Jul 2012 06:45:27 -0700 [thread overview]
Message-ID: <500EA6F7.6080609@cs.ucla.edu> (raw)
In-Reply-To: <jwv8ve9h6jp.fsf-monnier+emacs@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 285 bytes --]
On 07/24/2012 02:07 AM, Stefan Monnier wrote:
> Could you separate this part of the patch, since I don't know what you
> mean by "inlining by hand".
Sure, attached; this assumes the earlier patch in
<http://debbugs.gnu.org/cgi/bugreport.cgi?bug=11935#5>
has been applied and merged.
[-- Attachment #2: inline-by-hand.txt --]
[-- Type: text/plain, Size: 11390 bytes --]
2012-07-24 Paul Eggert <eggert@cs.ucla.edu>
* 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);
}
next prev parent reply other threads:[~2012-07-24 13:45 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-13 15:07 bug#11935: XINT etc. should be functions Paul Eggert
2012-07-14 2:20 ` bug#11935: [TRUNCATED MESSAGE 2746 87596] " Richard Stallman
2012-07-15 13:41 ` Paul Eggert
2012-07-15 22:06 ` Stefan Monnier
2012-07-16 14:54 ` Paul Eggert
2012-07-16 16:12 ` Eli Zaretskii
2012-07-16 21:40 ` Paul Eggert
2012-07-16 18:19 ` Richard Stallman
2012-07-16 22:46 ` Paul Eggert
2012-07-17 3:04 ` Eli Zaretskii
2012-07-17 3:54 ` Paul Eggert
2012-07-24 2:20 ` Paul Eggert
2012-07-24 9:07 ` Stefan Monnier
2012-07-24 13:45 ` Paul Eggert [this message]
2012-07-24 21:57 ` Stefan Monnier
2012-07-25 4:07 ` Paul Eggert
2012-07-15 14:41 ` Chong Yidong
2012-07-15 16:40 ` Paul Eggert
2012-07-16 2:22 ` Chong Yidong
2012-07-16 14:54 ` Paul Eggert
2013-06-06 15:56 ` Paul Eggert
2013-06-06 16:36 ` Andreas Schwab
2013-06-13 16:30 ` Paul Eggert
2013-06-06 16:42 ` Stefan Monnier
2013-06-09 0:52 ` Paul Eggert
2013-06-09 3:04 ` Stefan Monnier
2013-06-09 4:37 ` James Cloos
2013-06-09 6:59 ` Jan Djärv
2013-06-09 7:13 ` Paul Eggert
2013-06-09 15:57 ` Stefan Monnier
2013-06-13 14:45 ` Paul Eggert
2013-06-13 20:08 ` Stefan Monnier
2013-06-15 6:43 ` Paul Eggert
2013-06-15 14:22 ` Stefan Monnier
2013-06-17 6:05 ` Paul Eggert
2013-06-09 6:56 ` Jan Djärv
2013-06-09 7:23 ` Paul Eggert
2013-06-09 9:18 ` Jan Djärv
2013-06-09 14:25 ` Juanma Barranquero
2013-06-09 16:05 ` Jan Djärv
2013-06-10 13:40 ` Barry OReilly
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=500EA6F7.6080609@cs.ucla.edu \
--to=eggert@cs.ucla.edu \
--cc=11935@debbugs.gnu.org \
--cc=monnier@IRO.UMontreal.CA \
/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 external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.