diff options
| author | Stefan Monnier | 2009-11-06 18:47:48 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2009-11-06 18:47:48 +0000 |
| commit | 2de9f71c22f9def6adaa6782eea25bc569cb8561 (patch) | |
| tree | 399507700b025f007803c590ef825f5eea3f989d /src/lisp.h | |
| parent | 7ac65b38938cdee2916350bc0b16f21a00dca444 (diff) | |
| download | emacs-2de9f71c22f9def6adaa6782eea25bc569cb8561.tar.gz emacs-2de9f71c22f9def6adaa6782eea25bc569cb8561.zip | |
Let integers use up 2 tags to give them one extra bit and double their range.
* lisp.h (USE_2_TAGS_FOR_INTS): New macro.
(LISP_INT_TAG, case_Lisp_Int, LISP_STRING_TAG, LISP_INT_TAG_P): New macros.
(enum Lisp_Type): Use them. Give explicit values.
(Lisp_Type_Limit): Remove.
(XINT, XUINT, make_number) [!USE_LISP_UNION_TYPE]:
(MOST_NEGATIVE_FIXNUM, MOST_POSITIVE_FIXNUM, INTMASK):
Pay attention to USE_2_TAGS_FOR_INTS.
(INTEGERP): Use LISP_INT_TAG_P.
* fns.c (internal_equal): Simplify the default case.
(sxhash): Use case_Lisp_Int.
* data.c (wrong_type_argument): Don't check against Lisp_Type_Limit any more.
(Ftype_of): Use case_Lisp_Int.
(store_symval_forwarding): Take into account the fact that Ints can
now have more than one tag.
* buffer.c (syms_of_buffer): Use LISP_INT_TAG.
buffer_slot_type_mismatch):
* xfaces.c (face_attr_equal_p):
* print.c (print_object):
* alloc.c (mark_maybe_object, mark_object, survives_gc_p): Use case_Lisp_Int.
Diffstat (limited to 'src/lisp.h')
| -rw-r--r-- | src/lisp.h | 117 |
1 files changed, 82 insertions, 35 deletions
diff --git a/src/lisp.h b/src/lisp.h index 95759c18f51..65c88dcfab7 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -150,37 +150,68 @@ extern void die P_((const char *, const char *, int)) NO_RETURN; | |||
| 150 | 150 | ||
| 151 | /* Define the fundamental Lisp data structures. */ | 151 | /* Define the fundamental Lisp data structures. */ |
| 152 | 152 | ||
| 153 | /* If USE_2_TAGBITS_FOR_INTS is defined, then Lisp integers use | ||
| 154 | 2 tags, to give them one extra bit, thus extending their range from | ||
| 155 | e.g -2^28..2^28-1 to -2^29..2^29-1. */ | ||
| 156 | #define USE_2_TAGS_FOR_INTS | ||
| 157 | |||
| 158 | /* Making it work for the union case is too much trouble. */ | ||
| 159 | #ifdef USE_LISP_UNION_TYPE | ||
| 160 | # undef USE_2_TAGS_FOR_INTS | ||
| 161 | #endif | ||
| 162 | |||
| 153 | /* This is the set of Lisp data types. */ | 163 | /* This is the set of Lisp data types. */ |
| 154 | 164 | ||
| 165 | #if !defined USE_2_TAGS_FOR_INTS | ||
| 166 | # define LISP_INT_TAG Lisp_Int | ||
| 167 | # define case_Lisp_Int case Lisp_Int | ||
| 168 | # define LISP_STRING_TAG 4 | ||
| 169 | # define LISP_INT_TAG_P(x) ((x) == Lisp_Int) | ||
| 170 | #else | ||
| 171 | # define LISP_INT_TAG Lisp_Int0 | ||
| 172 | # define case_Lisp_Int case Lisp_Int0: case Lisp_Int1 | ||
| 173 | # ifdef USE_LSB_TAG | ||
| 174 | # define LISP_INT1_TAG 4 | ||
| 175 | # define LISP_STRING_TAG 1 | ||
| 176 | # define LISP_INT_TAG_P(x) (((x) & 3) == 0) | ||
| 177 | # else | ||
| 178 | # define LISP_INT1_TAG 1 | ||
| 179 | # define LISP_STRING_TAG 4 | ||
| 180 | # define LISP_INT_TAG_P(x) (((x) & 6) == 0) | ||
| 181 | # endif | ||
| 182 | #endif | ||
| 183 | |||
| 155 | enum Lisp_Type | 184 | enum Lisp_Type |
| 156 | { | 185 | { |
| 157 | /* Integer. XINT (obj) is the integer value. */ | 186 | /* Integer. XINT (obj) is the integer value. */ |
| 158 | Lisp_Int, | 187 | #ifdef USE_2_TAGS_FOR_INTS |
| 188 | Lisp_Int0 = 0, | ||
| 189 | Lisp_Int1 = LISP_INT1_TAG, | ||
| 190 | #else | ||
| 191 | Lisp_Int = 0, | ||
| 192 | #endif | ||
| 159 | 193 | ||
| 160 | /* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */ | 194 | /* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */ |
| 161 | Lisp_Symbol, | 195 | Lisp_Symbol = 2, |
| 162 | 196 | ||
| 163 | /* Miscellaneous. XMISC (object) points to a union Lisp_Misc, | 197 | /* Miscellaneous. XMISC (object) points to a union Lisp_Misc, |
| 164 | whose first member indicates the subtype. */ | 198 | whose first member indicates the subtype. */ |
| 165 | Lisp_Misc, | 199 | Lisp_Misc = 3, |
| 166 | 200 | ||
| 167 | /* String. XSTRING (object) points to a struct Lisp_String. | 201 | /* String. XSTRING (object) points to a struct Lisp_String. |
| 168 | The length of the string, and its contents, are stored therein. */ | 202 | The length of the string, and its contents, are stored therein. */ |
| 169 | Lisp_String, | 203 | Lisp_String = LISP_STRING_TAG, |
| 170 | 204 | ||
| 171 | /* Vector of Lisp objects, or something resembling it. | 205 | /* Vector of Lisp objects, or something resembling it. |
| 172 | XVECTOR (object) points to a struct Lisp_Vector, which contains | 206 | XVECTOR (object) points to a struct Lisp_Vector, which contains |
| 173 | the size and contents. The size field also contains the type | 207 | the size and contents. The size field also contains the type |
| 174 | information, if it's not a real vector object. */ | 208 | information, if it's not a real vector object. */ |
| 175 | Lisp_Vectorlike, | 209 | Lisp_Vectorlike = 5, |
| 176 | 210 | ||
| 177 | /* Cons. XCONS (object) points to a struct Lisp_Cons. */ | 211 | /* Cons. XCONS (object) points to a struct Lisp_Cons. */ |
| 178 | Lisp_Cons, | 212 | Lisp_Cons = 6, |
| 179 | |||
| 180 | Lisp_Float, | ||
| 181 | 213 | ||
| 182 | /* This is not a type code. It is for range checking. */ | 214 | Lisp_Float = 7, |
| 183 | Lisp_Type_Limit | ||
| 184 | }; | 215 | }; |
| 185 | 216 | ||
| 186 | /* This is the set of data types that share a common structure. | 217 | /* This is the set of data types that share a common structure. |
| @@ -353,12 +384,18 @@ enum pvec_type | |||
| 353 | 384 | ||
| 354 | #define TYPEMASK ((((EMACS_INT) 1) << GCTYPEBITS) - 1) | 385 | #define TYPEMASK ((((EMACS_INT) 1) << GCTYPEBITS) - 1) |
| 355 | #define XTYPE(a) ((enum Lisp_Type) (((EMACS_UINT) (a)) & TYPEMASK)) | 386 | #define XTYPE(a) ((enum Lisp_Type) (((EMACS_UINT) (a)) & TYPEMASK)) |
| 356 | #define XINT(a) (((EMACS_INT) (a)) >> GCTYPEBITS) | 387 | #ifdef USE_2_TAGS_FOR_INTS |
| 357 | #define XUINT(a) (((EMACS_UINT) (a)) >> GCTYPEBITS) | 388 | # define XINT(a) (((EMACS_INT) (a)) >> (GCTYPEBITS - 1)) |
| 389 | # define XUINT(a) (((EMACS_UINT) (a)) >> (GCTYPEBITS - 1)) | ||
| 390 | # define make_number(N) (((EMACS_INT) (N)) << (GCTYPEBITS - 1)) | ||
| 391 | #else | ||
| 392 | # define XINT(a) (((EMACS_INT) (a)) >> GCTYPEBITS) | ||
| 393 | # define XUINT(a) (((EMACS_UINT) (a)) >> GCTYPEBITS) | ||
| 394 | # define make_number(N) (((EMACS_INT) (N)) << GCTYPEBITS) | ||
| 395 | #endif | ||
| 358 | #define XSET(var, type, ptr) \ | 396 | #define XSET(var, type, ptr) \ |
| 359 | (eassert (XTYPE (ptr) == 0), /* Check alignment. */ \ | 397 | (eassert (XTYPE (ptr) == 0), /* Check alignment. */ \ |
| 360 | (var) = ((EMACS_INT) (type)) | ((EMACS_INT) (ptr))) | 398 | (var) = ((EMACS_INT) (type)) | ((EMACS_INT) (ptr))) |
| 361 | #define make_number(N) (((EMACS_INT) (N)) << GCTYPEBITS) | ||
| 362 | 399 | ||
| 363 | #define XPNTR(a) ((EMACS_INT) ((a) & ~TYPEMASK)) | 400 | #define XPNTR(a) ((EMACS_INT) ((a) & ~TYPEMASK)) |
| 364 | 401 | ||
| @@ -378,41 +415,43 @@ enum pvec_type | |||
| 378 | #define XFASTINT(a) ((a) + 0) | 415 | #define XFASTINT(a) ((a) + 0) |
| 379 | #define XSETFASTINT(a, b) ((a) = (b)) | 416 | #define XSETFASTINT(a, b) ((a) = (b)) |
| 380 | 417 | ||
| 381 | /* Extract the value of a Lisp_Object as a signed integer. */ | 418 | /* Extract the value of a Lisp_Object as a (un)signed integer. */ |
| 382 | 419 | ||
| 383 | #ifndef XINT /* Some machines need to do this differently. */ | 420 | #ifdef USE_2_TAGS_FOR_INTS |
| 384 | #define XINT(a) ((((EMACS_INT) (a)) << (BITS_PER_EMACS_INT - VALBITS)) \ | 421 | # define XINT(a) ((((EMACS_INT) (a)) << (GCTYPEBITS - 1)) >> (GCTYPEBITS - 1)) |
| 422 | # define XUINT(a) ((EMACS_UINT) ((a) & (1 + (VALMASK << 1)))) | ||
| 423 | # define make_number(N) ((((EMACS_INT) (N)) & (1 + (VALMASK << 1)))) | ||
| 424 | #else | ||
| 425 | # define XINT(a) ((((EMACS_INT) (a)) << (BITS_PER_EMACS_INT - VALBITS)) \ | ||
| 385 | >> (BITS_PER_EMACS_INT - VALBITS)) | 426 | >> (BITS_PER_EMACS_INT - VALBITS)) |
| 427 | # define XUINT(a) ((EMACS_UINT) ((a) & VALMASK)) | ||
| 428 | # define make_number(N) \ | ||
| 429 | ((((EMACS_INT) (N)) & VALMASK) | ((EMACS_INT) Lisp_Int) << VALBITS) | ||
| 386 | #endif | 430 | #endif |
| 387 | 431 | ||
| 388 | /* Extract the value as an unsigned integer. This is a basis | ||
| 389 | for extracting it as a pointer to a structure in storage. */ | ||
| 390 | |||
| 391 | #ifndef XUINT | ||
| 392 | #define XUINT(a) ((EMACS_UINT) ((a) & VALMASK)) | ||
| 393 | #endif | ||
| 394 | |||
| 395 | #ifndef XSET | ||
| 396 | #define XSET(var, type, ptr) \ | 432 | #define XSET(var, type, ptr) \ |
| 397 | ((var) = ((EMACS_INT)(type) << VALBITS) + ((EMACS_INT) (ptr) & VALMASK)) | 433 | ((var) = ((EMACS_INT)(type) << VALBITS) + ((EMACS_INT) (ptr) & VALMASK)) |
| 398 | #endif | ||
| 399 | |||
| 400 | /* Convert a C integer into a Lisp_Object integer. */ | ||
| 401 | 434 | ||
| 402 | #define make_number(N) \ | 435 | #define XPNTR(a) ((EMACS_UINT) ((a) & VALMASK)) |
| 403 | ((((EMACS_INT) (N)) & VALMASK) | ((EMACS_INT) Lisp_Int) << VALBITS) | ||
| 404 | 436 | ||
| 405 | #endif /* not USE_LSB_TAG */ | 437 | #endif /* not USE_LSB_TAG */ |
| 406 | 438 | ||
| 407 | #else /* USE_LISP_UNION_TYPE */ | 439 | #else /* USE_LISP_UNION_TYPE */ |
| 408 | 440 | ||
| 441 | #ifdef USE_2_TAGS_FOR_INTS | ||
| 442 | # error "USE_2_TAGS_FOR_INTS is not supported with USE_LISP_UNION_TYPE" | ||
| 443 | #endif | ||
| 444 | |||
| 409 | #define XHASH(a) ((a).i) | 445 | #define XHASH(a) ((a).i) |
| 410 | 446 | ||
| 411 | #define XTYPE(a) ((enum Lisp_Type) (a).u.type) | 447 | #define XTYPE(a) ((enum Lisp_Type) (a).u.type) |
| 412 | 448 | ||
| 413 | #ifdef EXPLICIT_SIGN_EXTEND | 449 | #ifdef EXPLICIT_SIGN_EXTEND |
| 414 | /* Make sure we sign-extend; compilers have been known to fail to do so. */ | 450 | /* Make sure we sign-extend; compilers have been known to fail to do so. |
| 415 | #define XINT(a) (((a).s.val << (BITS_PER_EMACS_INT - VALBITS)) \ | 451 | We additionally cast to EMACS_INT since it seems that some compilers |
| 452 | have been known to fail to do so, even though the bitfield is declared | ||
| 453 | as EMACS_INT already. */ | ||
| 454 | #define XINT(a) ((((EMACS_INT) (a).s.val) << (BITS_PER_EMACS_INT - VALBITS)) \ | ||
| 416 | >> (BITS_PER_EMACS_INT - VALBITS)) | 455 | >> (BITS_PER_EMACS_INT - VALBITS)) |
| 417 | #else | 456 | #else |
| 418 | #define XINT(a) ((a).s.val) | 457 | #define XINT(a) ((a).s.val) |
| @@ -491,11 +530,19 @@ extern size_t pure_size; | |||
| 491 | /* Largest and smallest representable fixnum values. These are the C | 530 | /* Largest and smallest representable fixnum values. These are the C |
| 492 | values. */ | 531 | values. */ |
| 493 | 532 | ||
| 494 | #define MOST_NEGATIVE_FIXNUM - ((EMACS_INT) 1 << (VALBITS - 1)) | 533 | #ifdef USE_2_TAGS_FOR_INTS |
| 495 | #define MOST_POSITIVE_FIXNUM (((EMACS_INT) 1 << (VALBITS - 1)) - 1) | 534 | # define MOST_NEGATIVE_FIXNUM - ((EMACS_INT) 1 << VALBITS) |
| 535 | # define MOST_POSITIVE_FIXNUM (((EMACS_INT) 1 << VALBITS) - 1) | ||
| 496 | /* Mask indicating the significant bits of a Lisp_Int. | 536 | /* Mask indicating the significant bits of a Lisp_Int. |
| 497 | I.e. (x & INTMASK) == XUINT (make_number (x)). */ | 537 | I.e. (x & INTMASK) == XUINT (make_number (x)). */ |
| 498 | #define INTMASK ((((EMACS_INT) 1) << VALBITS) - 1) | 538 | # define INTMASK ((((EMACS_INT) 1) << (VALBITS + 1)) - 1) |
| 539 | #else | ||
| 540 | # define MOST_NEGATIVE_FIXNUM - ((EMACS_INT) 1 << (VALBITS - 1)) | ||
| 541 | # define MOST_POSITIVE_FIXNUM (((EMACS_INT) 1 << (VALBITS - 1)) - 1) | ||
| 542 | /* Mask indicating the significant bits of a Lisp_Int. | ||
| 543 | I.e. (x & INTMASK) == XUINT (make_number (x)). */ | ||
| 544 | # define INTMASK ((((EMACS_INT) 1) << VALBITS) - 1) | ||
| 545 | #endif | ||
| 499 | 546 | ||
| 500 | /* Value is non-zero if I doesn't fit into a Lisp fixnum. It is | 547 | /* Value is non-zero if I doesn't fit into a Lisp fixnum. It is |
| 501 | written this way so that it also works if I is of unsigned | 548 | written this way so that it also works if I is of unsigned |
| @@ -1506,7 +1553,7 @@ typedef struct { | |||
| 1506 | #define NUMBERP(x) (INTEGERP (x) || FLOATP (x)) | 1553 | #define NUMBERP(x) (INTEGERP (x) || FLOATP (x)) |
| 1507 | #define NATNUMP(x) (INTEGERP (x) && XINT (x) >= 0) | 1554 | #define NATNUMP(x) (INTEGERP (x) && XINT (x) >= 0) |
| 1508 | 1555 | ||
| 1509 | #define INTEGERP(x) (XTYPE ((x)) == Lisp_Int) | 1556 | #define INTEGERP(x) (LISP_INT_TAG_P (XTYPE ((x)))) |
| 1510 | #define SYMBOLP(x) (XTYPE ((x)) == Lisp_Symbol) | 1557 | #define SYMBOLP(x) (XTYPE ((x)) == Lisp_Symbol) |
| 1511 | #define MISCP(x) (XTYPE ((x)) == Lisp_Misc) | 1558 | #define MISCP(x) (XTYPE ((x)) == Lisp_Misc) |
| 1512 | #define VECTORLIKEP(x) (XTYPE ((x)) == Lisp_Vectorlike) | 1559 | #define VECTORLIKEP(x) (XTYPE ((x)) == Lisp_Vectorlike) |