diff options
| author | Paul Eggert | 2015-01-05 09:07:45 -0800 |
|---|---|---|
| committer | Paul Eggert | 2015-01-05 10:15:04 -0800 |
| commit | bc78ff2603b8c062dbd8f93f421c3412e36e343f (patch) | |
| tree | 52f5ad17e9a61db8287ed4a026abfb4dc64ccd16 | |
| parent | 58f2d6ef32b28a787fcc4e0d98b3f331ceb2a68c (diff) | |
| download | emacs-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/ChangeLog | 3 | ||||
| -rw-r--r-- | lib-src/make-docfile.c | 10 | ||||
| -rw-r--r-- | src/ChangeLog | 18 | ||||
| -rw-r--r-- | src/lisp.h | 59 |
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 @@ | |||
| 1 | 2015-01-05 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2015-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 @@ | |||
| 1 | 2015-01-05 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2015-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 | ||
| 448 | enum Lisp_Type | 453 | enum 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); | |||
| 604 | INLINE bool SUBRP (Lisp_Object); | 609 | INLINE bool SUBRP (Lisp_Object); |
| 605 | INLINE bool (SYMBOLP) (Lisp_Object); | 610 | INLINE bool (SYMBOLP) (Lisp_Object); |
| 606 | INLINE bool (VECTORLIKEP) (Lisp_Object); | 611 | INLINE bool (VECTORLIKEP) (Lisp_Object); |
| 612 | INLINE struct Lisp_Symbol *XSYMBOL (Lisp_Object); | ||
| 613 | INLINE void *(XUNTAGBASE) (Lisp_Object, int, void *); | ||
| 607 | INLINE bool WINDOWP (Lisp_Object); | 614 | INLINE bool WINDOWP (Lisp_Object); |
| 608 | INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object); | 615 | INLINE 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)) | |||
| 818 | LISP_MACRO_DEFUN (XFASTINT, EMACS_INT, (Lisp_Object a), (a)) | 829 | LISP_MACRO_DEFUN (XFASTINT, EMACS_INT, (Lisp_Object a), (a)) |
| 819 | LISP_MACRO_DEFUN (XTYPE, enum Lisp_Type, (Lisp_Object a), (a)) | 830 | LISP_MACRO_DEFUN (XTYPE, enum Lisp_Type, (Lisp_Object a), (a)) |
| 820 | LISP_MACRO_DEFUN (XUNTAG, void *, (Lisp_Object a, int type), (a, type)) | 831 | LISP_MACRO_DEFUN (XUNTAG, void *, (Lisp_Object a, int type), (a, type)) |
| 832 | LISP_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. */ | ||
| 896 | INLINE void * | ||
| 897 | XUNTAGBASE (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. */ |
| 882 | INLINE void * | 905 | INLINE void * |
| 883 | XUNTAG (Lisp_Object a, int type) | 906 | XUNTAG (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) | |||
| 1032 | INLINE Lisp_Object | 1050 | INLINE Lisp_Object |
| 1033 | make_lisp_symbol (struct Lisp_Symbol *sym) | 1051 | make_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 | ||
| 1038 | INLINE Lisp_Object | 1059 | INLINE Lisp_Object |