]> git.eshelyaron.com Git - emacs.git/commitdiff
Use 0 for Qnil
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 5 Jan 2015 17:07:45 +0000 (09:07 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 5 Jan 2015 18:15:04 +0000 (10:15 -0800)
Fixes Bug#15880.
If USE_LSB_TAG, arrange for the representation of Qnil to be zero so
that NILP (x) is equivalent to testing whether x is 0 at the
machine level.  The overall effects of this and the previous patch
shrink the size of the text segment by 2.3% and speeds up
compilation of all the .elc files by about 0.5% on my platform,
which is Fedora 20 x86-64.
* lib-src/make-docfile.c (compare_globals):
* src/lisp.h (lisp_h_XPNTR, lisp_h_XSYMBOL, lisp_h_XUNTAG)
(make_lisp_symbol) [USE_LSB_TAG]:
Symbols now tag the difference from lispsym, not the pointer.
(lisp_h_XUNTAGBASE, TAG_SYMPTR): New macros.
(Lisp_Int0, Lisp_Int1, Lisp_Symbol, Lisp_Misc, Lisp_String, Lisp_Cons):
Renumber so that Lisp_Symbol is 0, so that Qnil is zero.
(XSYMBOL): New forward decl.
(XUNTAGBASE): New function.
(XUNTAG): Use it.

lib-src/ChangeLog
lib-src/make-docfile.c
src/ChangeLog
src/lisp.h

index 8bdf7d1fb16a255e50eb37febae0af636b9b231c..9a1fc7a3e9fa3b2cfe281dcdc2319f8407b572d0 100644 (file)
@@ -1,5 +1,8 @@
 2015-01-05  Paul Eggert  <eggert@cs.ucla.edu>
 
+       Use 0 for Qnil
+       * make-docfile.c (compare_globals): Consider 'nil' to be the least.
+
        Compute C decls for DEFSYMs automatically
        Fixes Bug#15880.
        * make-docfile.c: Revamp to generate table of symbols, too.
index b05a634eb75a9ab5bd24219d7c7378cd7c492f60..22c4bad2e3f5839f552fc9bef673bd4b898ecff6 100644 (file)
@@ -613,6 +613,16 @@ compare_globals (const void *a, const void *b)
   if (ga->type != gb->type)
     return ga->type - gb->type;
 
+  /* Consider "nil" to be the least, so that aQnil is firat.  That
+     way, Qnil's internal representation is zero, which is a bit faster.  */
+  if (ga->type == SYMBOL)
+    {
+      bool a_nil = strcmp (ga->name, "Qnil") == 0;
+      bool b_nil = strcmp (gb->name, "Qnil") == 0;
+      if (a_nil | b_nil)
+       return b_nil - a_nil;
+    }
+
   return strcmp (ga->name, gb->name);
 }
 
index 627379947471dcf51b743cbe55d3baa2a7563408..b068056667b0ec7b1da4e6adede0dce04679d274 100644 (file)
@@ -1,5 +1,23 @@
 2015-01-05  Paul Eggert  <eggert@cs.ucla.edu>
 
+       Use 0 for Qnil
+       Fixes Bug#15880.
+       If USE_LSB_TAG, arrange for the representation of Qnil to be zero so
+       that NILP (x) is equivalent to testing whether x is 0 at the
+       machine level.  The overall effects of this and the previous patch
+       shrink the size of the text segment by 2.3% and speeds up
+       compilation of all the .elc files by about 0.5% on my platform,
+       which is Fedora 20 x86-64.
+       * lisp.h (lisp_h_XPNTR, lisp_h_XSYMBOL, lisp_h_XUNTAG)
+       (make_lisp_symbol) [USE_LSB_TAG]:
+       Symbols now tag the difference from lispsym, not the pointer.
+       (lisp_h_XUNTAGBASE, TAG_SYMPTR): New macros.
+       (Lisp_Int0, Lisp_Int1, Lisp_Symbol, Lisp_Misc, Lisp_String, Lisp_Cons):
+       Renumber so that Lisp_Symbol is 0, so that Qnil is zero.
+       (XSYMBOL): New forward decl.
+       (XUNTAGBASE): New function.
+       (XUNTAG): Use it.
+
        Compute C decls for DEFSYMs automatically
        Fixes Bug#15880.
        This patch also makes Q constants (e.g., Qnil) constant addresses
index 962fed4d81f2895dd305a52d6e295d27d8be457f..fc04ab9ad3fa7043e992c3a05e575ace3f227542 100644 (file)
@@ -354,9 +354,11 @@ error !;
 #define lisp_h_XCONS(a) \
    (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons))
 #define lisp_h_XHASH(a) XUINT (a)
-#define lisp_h_XPNTR(a) ((void *) (intptr_t) (XLI (a) & VALMASK))
+#define lisp_h_XPNTR(a) \
+   (SYMBOLP (a) ? XSYMBOL (a) : (void *) ((intptr_t) (XLI (a) & VALMASK)))
 #define lisp_h_XSYMBOL(a) \
-   (eassert (SYMBOLP (a)), (struct Lisp_Symbol *) XUNTAG (a, Lisp_Symbol))
+   (eassert (SYMBOLP (a)), \
+    (struct Lisp_Symbol *) XUNTAGBASE (a, Lisp_Symbol, lispsym))
 #ifndef GC_CHECK_CONS_LIST
 # define lisp_h_check_cons_list() ((void) 0)
 #endif
@@ -366,7 +368,9 @@ error !;
 # define lisp_h_XFASTINT(a) XINT (a)
 # define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS)
 # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
-# define lisp_h_XUNTAG(a, type) ((void *) (XLI (a) - (type)))
+# define lisp_h_XUNTAG(a, type) XUNTAGBASE (a, type, 0)
+# define lisp_h_XUNTAGBASE(a, type, base) \
+    ((void *) ((char *) (base) - (type) + (intptr_t) XLI (a)))
 #endif
 
 /* When compiling via gcc -O0, define the key operations as macros, as
@@ -408,6 +412,7 @@ error !;
 #  define XINT(a) lisp_h_XINT (a)
 #  define XTYPE(a) lisp_h_XTYPE (a)
 #  define XUNTAG(a, type) lisp_h_XUNTAG (a, type)
+#  define XUNTAGBASE(a, type, base) lisp_h_XUNTAGBASE (a, type, base)
 # endif
 #endif
 
@@ -447,20 +452,20 @@ error !;
 
 enum Lisp_Type
   {
-    /* Integer.  XINT (obj) is the integer value.  */
-    Lisp_Int0 = 0,
-    Lisp_Int1 = USE_LSB_TAG ? 1 << INTTYPEBITS : 1,
-
     /* Symbol.  XSYMBOL (object) points to a struct Lisp_Symbol.  */
-    Lisp_Symbol = 2,
+    Lisp_Symbol = 0,
 
     /* Miscellaneous.  XMISC (object) points to a union Lisp_Misc,
        whose first member indicates the subtype.  */
-    Lisp_Misc = 3,
+    Lisp_Misc = 1,
+
+    /* Integer.  XINT (obj) is the integer value.  */
+    Lisp_Int0 = 2,
+    Lisp_Int1 = USE_LSB_TAG ? 6 : 3,
 
     /* String.  XSTRING (object) points to a struct Lisp_String.
        The length of the string, and its contents, are stored therein.  */
-    Lisp_String = USE_LSB_TAG ? 1 : 1 << INTTYPEBITS,
+    Lisp_String = 4,
 
     /* Vector of Lisp objects, or something resembling it.
        XVECTOR (object) points to a struct Lisp_Vector, which contains
@@ -469,7 +474,7 @@ enum Lisp_Type
     Lisp_Vectorlike = 5,
 
     /* Cons.  XCONS (object) points to a struct Lisp_Cons.  */
-    Lisp_Cons = 6,
+    Lisp_Cons = USE_LSB_TAG ? 3 : 6,
 
     Lisp_Float = 7
   };
@@ -604,6 +609,8 @@ INLINE bool SUB_CHAR_TABLE_P (Lisp_Object);
 INLINE bool SUBRP (Lisp_Object);
 INLINE bool (SYMBOLP) (Lisp_Object);
 INLINE bool (VECTORLIKEP) (Lisp_Object);
+INLINE struct Lisp_Symbol *XSYMBOL (Lisp_Object);
+INLINE void *(XUNTAGBASE) (Lisp_Object, int, void *);
 INLINE bool WINDOWP (Lisp_Object);
 INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object);
 
@@ -720,6 +727,10 @@ struct Lisp_Symbol
 #define TAG_PTR(tag, ptr) \
   ((USE_LSB_TAG ? (tag) : (EMACS_UINT) (tag) << VALBITS) + (uintptr_t) (ptr))
 
+/* Yield an integer that tags PTR as a symbol.  */
+#define TAG_SYMPTR(ptr) \
+  TAG_PTR (Lisp_Symbol, (char *) (ptr) - (char *) (USE_LSB_TAG ? lispsym : 0))
+
 /* Declare extern constants for Lisp symbols.  These can be helpful
    when using a debugger like GDB, on older platforms where the debug
    format does not represent C macros.  Athough these symbols are
@@ -727,7 +738,7 @@ struct Lisp_Symbol
 #define DEFINE_LISP_SYMBOL_BEGIN(name) \
    DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name)
 #define DEFINE_LISP_SYMBOL_END(name) \
-   DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_PTR (Lisp_Symbol, name)))
+   DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_SYMPTR (name)))
 
 #include "globals.h"
 
@@ -818,6 +829,8 @@ LISP_MACRO_DEFUN (XINT, EMACS_INT, (Lisp_Object a), (a))
 LISP_MACRO_DEFUN (XFASTINT, EMACS_INT, (Lisp_Object a), (a))
 LISP_MACRO_DEFUN (XTYPE, enum Lisp_Type, (Lisp_Object a), (a))
 LISP_MACRO_DEFUN (XUNTAG, void *, (Lisp_Object a, int type), (a, type))
+LISP_MACRO_DEFUN (XUNTAGBASE, void *, (Lisp_Object a, int type, void *base),
+                 (a, type, base))
 
 #else /* ! USE_LSB_TAG */
 
@@ -878,16 +891,21 @@ XTYPE (Lisp_Object a)
   return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
 }
 
+/* Extract A's pointer value, assuming A's type is TYPE.
+   If USE_LSB_TAG, add BASE to A's pointer value while extracting.  */
+INLINE void *
+XUNTAGBASE (Lisp_Object a, int type, void *base)
+{
+  char *b = USE_LSB_TAG ? base : 0;
+  intptr_t i = USE_LSB_TAG ? XLI (a) - type : XLI (a) & VALMASK;
+  return b + i;
+}
+
 /* Extract A's pointer value, assuming A's type is TYPE.  */
 INLINE void *
 XUNTAG (Lisp_Object a, int type)
 {
-  if (USE_LSB_TAG)
-    {
-      intptr_t i = XLI (a) - type;
-      return (void *) i;
-    }
-  return XPNTR (a);
+  return XUNTAGBASE (a, type, 0);
 }
 
 #endif /* ! USE_LSB_TAG */
@@ -1032,7 +1050,10 @@ make_lisp_ptr (void *ptr, enum Lisp_Type type)
 INLINE Lisp_Object
 make_lisp_symbol (struct Lisp_Symbol *sym)
 {
-  return make_lisp_ptr (sym, Lisp_Symbol);
+  Lisp_Object a = XIL (TAG_SYMPTR (sym));
+  eassert (XTYPE (a) == Lisp_Symbol
+          && XUNTAGBASE (a, Lisp_Symbol, lispsym) == sym);
+  return a;
 }
 
 INLINE Lisp_Object