aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2015-01-05 09:07:45 -0800
committerPaul Eggert2015-01-05 10:15:04 -0800
commitbc78ff2603b8c062dbd8f93f421c3412e36e343f (patch)
tree52f5ad17e9a61db8287ed4a026abfb4dc64ccd16
parent58f2d6ef32b28a787fcc4e0d98b3f331ceb2a68c (diff)
downloademacs-bc78ff2603b8c062dbd8f93f421c3412e36e343f.tar.gz
emacs-bc78ff2603b8c062dbd8f93f421c3412e36e343f.zip
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. * 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.
-rw-r--r--lib-src/ChangeLog3
-rw-r--r--lib-src/make-docfile.c10
-rw-r--r--src/ChangeLog18
-rw-r--r--src/lisp.h59
4 files changed, 71 insertions, 19 deletions
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index 8bdf7d1fb16..9a1fc7a3e9f 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,5 +1,8 @@
12015-01-05 Paul Eggert <eggert@cs.ucla.edu> 12015-01-05 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 Use 0 for Qnil
4 * make-docfile.c (compare_globals): Consider 'nil' to be the least.
5
3 Compute C decls for DEFSYMs automatically 6 Compute C decls for DEFSYMs automatically
4 Fixes Bug#15880. 7 Fixes Bug#15880.
5 * make-docfile.c: Revamp to generate table of symbols, too. 8 * make-docfile.c: Revamp to generate table of symbols, too.
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c
index b05a634eb75..22c4bad2e3f 100644
--- a/lib-src/make-docfile.c
+++ b/lib-src/make-docfile.c
@@ -613,6 +613,16 @@ compare_globals (const void *a, const void *b)
613 if (ga->type != gb->type) 613 if (ga->type != gb->type)
614 return ga->type - gb->type; 614 return ga->type - gb->type;
615 615
616 /* Consider "nil" to be the least, so that aQnil is firat. That
617 way, Qnil's internal representation is zero, which is a bit faster. */
618 if (ga->type == SYMBOL)
619 {
620 bool a_nil = strcmp (ga->name, "Qnil") == 0;
621 bool b_nil = strcmp (gb->name, "Qnil") == 0;
622 if (a_nil | b_nil)
623 return b_nil - a_nil;
624 }
625
616 return strcmp (ga->name, gb->name); 626 return strcmp (ga->name, gb->name);
617} 627}
618 628
diff --git a/src/ChangeLog b/src/ChangeLog
index 62737994747..b068056667b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,23 @@
12015-01-05 Paul Eggert <eggert@cs.ucla.edu> 12015-01-05 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 Use 0 for Qnil
4 Fixes Bug#15880.
5 If USE_LSB_TAG, arrange for the representation of Qnil to be zero so
6 that NILP (x) is equivalent to testing whether x is 0 at the
7 machine level. The overall effects of this and the previous patch
8 shrink the size of the text segment by 2.3% and speeds up
9 compilation of all the .elc files by about 0.5% on my platform,
10 which is Fedora 20 x86-64.
11 * lisp.h (lisp_h_XPNTR, lisp_h_XSYMBOL, lisp_h_XUNTAG)
12 (make_lisp_symbol) [USE_LSB_TAG]:
13 Symbols now tag the difference from lispsym, not the pointer.
14 (lisp_h_XUNTAGBASE, TAG_SYMPTR): New macros.
15 (Lisp_Int0, Lisp_Int1, Lisp_Symbol, Lisp_Misc, Lisp_String, Lisp_Cons):
16 Renumber so that Lisp_Symbol is 0, so that Qnil is zero.
17 (XSYMBOL): New forward decl.
18 (XUNTAGBASE): New function.
19 (XUNTAG): Use it.
20
3 Compute C decls for DEFSYMs automatically 21 Compute C decls for DEFSYMs automatically
4 Fixes Bug#15880. 22 Fixes Bug#15880.
5 This patch also makes Q constants (e.g., Qnil) constant addresses 23 This patch also makes Q constants (e.g., Qnil) constant addresses
diff --git a/src/lisp.h b/src/lisp.h
index 962fed4d81f..fc04ab9ad3f 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -354,9 +354,11 @@ error !;
354#define lisp_h_XCONS(a) \ 354#define lisp_h_XCONS(a) \
355 (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons)) 355 (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons))
356#define lisp_h_XHASH(a) XUINT (a) 356#define lisp_h_XHASH(a) XUINT (a)
357#define lisp_h_XPNTR(a) ((void *) (intptr_t) (XLI (a) & VALMASK)) 357#define lisp_h_XPNTR(a) \
358 (SYMBOLP (a) ? XSYMBOL (a) : (void *) ((intptr_t) (XLI (a) & VALMASK)))
358#define lisp_h_XSYMBOL(a) \ 359#define lisp_h_XSYMBOL(a) \
359 (eassert (SYMBOLP (a)), (struct Lisp_Symbol *) XUNTAG (a, Lisp_Symbol)) 360 (eassert (SYMBOLP (a)), \
361 (struct Lisp_Symbol *) XUNTAGBASE (a, Lisp_Symbol, lispsym))
360#ifndef GC_CHECK_CONS_LIST 362#ifndef GC_CHECK_CONS_LIST
361# define lisp_h_check_cons_list() ((void) 0) 363# define lisp_h_check_cons_list() ((void) 0)
362#endif 364#endif
@@ -366,7 +368,9 @@ error !;
366# define lisp_h_XFASTINT(a) XINT (a) 368# define lisp_h_XFASTINT(a) XINT (a)
367# define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS) 369# define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS)
368# define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK)) 370# define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
369# define lisp_h_XUNTAG(a, type) ((void *) (XLI (a) - (type))) 371# define lisp_h_XUNTAG(a, type) XUNTAGBASE (a, type, 0)
372# define lisp_h_XUNTAGBASE(a, type, base) \
373 ((void *) ((char *) (base) - (type) + (intptr_t) XLI (a)))
370#endif 374#endif
371 375
372/* When compiling via gcc -O0, define the key operations as macros, as 376/* When compiling via gcc -O0, define the key operations as macros, as
@@ -408,6 +412,7 @@ error !;
408# define XINT(a) lisp_h_XINT (a) 412# define XINT(a) lisp_h_XINT (a)
409# define XTYPE(a) lisp_h_XTYPE (a) 413# define XTYPE(a) lisp_h_XTYPE (a)
410# define XUNTAG(a, type) lisp_h_XUNTAG (a, type) 414# define XUNTAG(a, type) lisp_h_XUNTAG (a, type)
415# define XUNTAGBASE(a, type, base) lisp_h_XUNTAGBASE (a, type, base)
411# endif 416# endif
412#endif 417#endif
413 418
@@ -447,20 +452,20 @@ error !;
447 452
448enum Lisp_Type 453enum Lisp_Type
449 { 454 {
450 /* Integer. XINT (obj) is the integer value. */
451 Lisp_Int0 = 0,
452 Lisp_Int1 = USE_LSB_TAG ? 1 << INTTYPEBITS : 1,
453
454 /* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */ 455 /* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */
455 Lisp_Symbol = 2, 456 Lisp_Symbol = 0,
456 457
457 /* Miscellaneous. XMISC (object) points to a union Lisp_Misc, 458 /* Miscellaneous. XMISC (object) points to a union Lisp_Misc,
458 whose first member indicates the subtype. */ 459 whose first member indicates the subtype. */
459 Lisp_Misc = 3, 460 Lisp_Misc = 1,
461
462 /* Integer. XINT (obj) is the integer value. */
463 Lisp_Int0 = 2,
464 Lisp_Int1 = USE_LSB_TAG ? 6 : 3,
460 465
461 /* String. XSTRING (object) points to a struct Lisp_String. 466 /* String. XSTRING (object) points to a struct Lisp_String.
462 The length of the string, and its contents, are stored therein. */ 467 The length of the string, and its contents, are stored therein. */
463 Lisp_String = USE_LSB_TAG ? 1 : 1 << INTTYPEBITS, 468 Lisp_String = 4,
464 469
465 /* Vector of Lisp objects, or something resembling it. 470 /* Vector of Lisp objects, or something resembling it.
466 XVECTOR (object) points to a struct Lisp_Vector, which contains 471 XVECTOR (object) points to a struct Lisp_Vector, which contains
@@ -469,7 +474,7 @@ enum Lisp_Type
469 Lisp_Vectorlike = 5, 474 Lisp_Vectorlike = 5,
470 475
471 /* Cons. XCONS (object) points to a struct Lisp_Cons. */ 476 /* Cons. XCONS (object) points to a struct Lisp_Cons. */
472 Lisp_Cons = 6, 477 Lisp_Cons = USE_LSB_TAG ? 3 : 6,
473 478
474 Lisp_Float = 7 479 Lisp_Float = 7
475 }; 480 };
@@ -604,6 +609,8 @@ INLINE bool SUB_CHAR_TABLE_P (Lisp_Object);
604INLINE bool SUBRP (Lisp_Object); 609INLINE bool SUBRP (Lisp_Object);
605INLINE bool (SYMBOLP) (Lisp_Object); 610INLINE bool (SYMBOLP) (Lisp_Object);
606INLINE bool (VECTORLIKEP) (Lisp_Object); 611INLINE bool (VECTORLIKEP) (Lisp_Object);
612INLINE struct Lisp_Symbol *XSYMBOL (Lisp_Object);
613INLINE void *(XUNTAGBASE) (Lisp_Object, int, void *);
607INLINE bool WINDOWP (Lisp_Object); 614INLINE bool WINDOWP (Lisp_Object);
608INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object); 615INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object);
609 616
@@ -720,6 +727,10 @@ struct Lisp_Symbol
720#define TAG_PTR(tag, ptr) \ 727#define TAG_PTR(tag, ptr) \
721 ((USE_LSB_TAG ? (tag) : (EMACS_UINT) (tag) << VALBITS) + (uintptr_t) (ptr)) 728 ((USE_LSB_TAG ? (tag) : (EMACS_UINT) (tag) << VALBITS) + (uintptr_t) (ptr))
722 729
730/* Yield an integer that tags PTR as a symbol. */
731#define TAG_SYMPTR(ptr) \
732 TAG_PTR (Lisp_Symbol, (char *) (ptr) - (char *) (USE_LSB_TAG ? lispsym : 0))
733
723/* Declare extern constants for Lisp symbols. These can be helpful 734/* Declare extern constants for Lisp symbols. These can be helpful
724 when using a debugger like GDB, on older platforms where the debug 735 when using a debugger like GDB, on older platforms where the debug
725 format does not represent C macros. Athough these symbols are 736 format does not represent C macros. Athough these symbols are
@@ -727,7 +738,7 @@ struct Lisp_Symbol
727#define DEFINE_LISP_SYMBOL_BEGIN(name) \ 738#define DEFINE_LISP_SYMBOL_BEGIN(name) \
728 DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) 739 DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name)
729#define DEFINE_LISP_SYMBOL_END(name) \ 740#define DEFINE_LISP_SYMBOL_END(name) \
730 DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_PTR (Lisp_Symbol, name))) 741 DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_SYMPTR (name)))
731 742
732#include "globals.h" 743#include "globals.h"
733 744
@@ -818,6 +829,8 @@ LISP_MACRO_DEFUN (XINT, EMACS_INT, (Lisp_Object a), (a))
818LISP_MACRO_DEFUN (XFASTINT, EMACS_INT, (Lisp_Object a), (a)) 829LISP_MACRO_DEFUN (XFASTINT, EMACS_INT, (Lisp_Object a), (a))
819LISP_MACRO_DEFUN (XTYPE, enum Lisp_Type, (Lisp_Object a), (a)) 830LISP_MACRO_DEFUN (XTYPE, enum Lisp_Type, (Lisp_Object a), (a))
820LISP_MACRO_DEFUN (XUNTAG, void *, (Lisp_Object a, int type), (a, type)) 831LISP_MACRO_DEFUN (XUNTAG, void *, (Lisp_Object a, int type), (a, type))
832LISP_MACRO_DEFUN (XUNTAGBASE, void *, (Lisp_Object a, int type, void *base),
833 (a, type, base))
821 834
822#else /* ! USE_LSB_TAG */ 835#else /* ! USE_LSB_TAG */
823 836
@@ -878,16 +891,21 @@ XTYPE (Lisp_Object a)
878 return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS; 891 return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
879} 892}
880 893
894/* Extract A's pointer value, assuming A's type is TYPE.
895 If USE_LSB_TAG, add BASE to A's pointer value while extracting. */
896INLINE void *
897XUNTAGBASE (Lisp_Object a, int type, void *base)
898{
899 char *b = USE_LSB_TAG ? base : 0;
900 intptr_t i = USE_LSB_TAG ? XLI (a) - type : XLI (a) & VALMASK;
901 return b + i;
902}
903
881/* Extract A's pointer value, assuming A's type is TYPE. */ 904/* Extract A's pointer value, assuming A's type is TYPE. */
882INLINE void * 905INLINE void *
883XUNTAG (Lisp_Object a, int type) 906XUNTAG (Lisp_Object a, int type)
884{ 907{
885 if (USE_LSB_TAG) 908 return XUNTAGBASE (a, type, 0);
886 {
887 intptr_t i = XLI (a) - type;
888 return (void *) i;
889 }
890 return XPNTR (a);
891} 909}
892 910
893#endif /* ! USE_LSB_TAG */ 911#endif /* ! USE_LSB_TAG */
@@ -1032,7 +1050,10 @@ make_lisp_ptr (void *ptr, enum Lisp_Type type)
1032INLINE Lisp_Object 1050INLINE Lisp_Object
1033make_lisp_symbol (struct Lisp_Symbol *sym) 1051make_lisp_symbol (struct Lisp_Symbol *sym)
1034{ 1052{
1035 return make_lisp_ptr (sym, Lisp_Symbol); 1053 Lisp_Object a = XIL (TAG_SYMPTR (sym));
1054 eassert (XTYPE (a) == Lisp_Symbol
1055 && XUNTAGBASE (a, Lisp_Symbol, lispsym) == sym);
1056 return a;
1036} 1057}
1037 1058
1038INLINE Lisp_Object 1059INLINE Lisp_Object