mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-12-03 08:30:09 +00:00
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.
This commit is contained in:
parent
7ac65b3893
commit
2de9f71c22
3
etc/NEWS
3
etc/NEWS
@ -49,6 +49,9 @@ were loaded.
|
||||
|
||||
* Changes in Emacs 23.2
|
||||
|
||||
** The maximum size of buffers (as well as the largest fixnum) is doubled.
|
||||
On typical 32bit systems, buffers can now be up to 512MB.
|
||||
|
||||
** Function arguments in *Help* buffers are now in uppercase by default.
|
||||
You can customize the new variable `help-downcase-arguments' to change it.
|
||||
|
||||
|
@ -1,3 +1,31 @@
|
||||
2009-11-06 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
Let integers use up 2 tags to give them one extra bit and thus 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.
|
||||
|
||||
|
||||
2009-11-06 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* s/msdos.h (SYSTEM_PURESIZE_EXTRA): Reduce by further 30K.
|
||||
|
@ -4149,8 +4149,7 @@ mark_maybe_object (obj)
|
||||
mark_p = (live_misc_p (m, po) && !XMISCANY (obj)->gcmarkbit);
|
||||
break;
|
||||
|
||||
case Lisp_Int:
|
||||
case Lisp_Type_Limit:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -5713,7 +5712,7 @@ mark_object (arg)
|
||||
FLOAT_MARK (XFLOAT (obj));
|
||||
break;
|
||||
|
||||
case Lisp_Int:
|
||||
case_Lisp_Int:
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -5799,7 +5798,7 @@ survives_gc_p (obj)
|
||||
|
||||
switch (XTYPE (obj))
|
||||
{
|
||||
case Lisp_Int:
|
||||
case_Lisp_Int:
|
||||
survives_p = 1;
|
||||
break;
|
||||
|
||||
|
10
src/buffer.c
10
src/buffer.c
@ -4573,7 +4573,7 @@ buffer_slot_type_mismatch (newval, type)
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Lisp_Int: predicate = Qintegerp; break;
|
||||
case_Lisp_Int: predicate = Qintegerp; break;
|
||||
case Lisp_String: predicate = Qstringp; break;
|
||||
case Lisp_Symbol: predicate = Qsymbolp; break;
|
||||
default: abort ();
|
||||
@ -5738,17 +5738,17 @@ Format with `format-mode-line' to produce a string value. */);
|
||||
doc: /* *Non-nil if searches and matches should ignore case. */);
|
||||
|
||||
DEFVAR_PER_BUFFER ("fill-column", ¤t_buffer->fill_column,
|
||||
make_number (Lisp_Int),
|
||||
make_number (LISP_INT_TAG),
|
||||
doc: /* *Column beyond which automatic line-wrapping should happen.
|
||||
Interactively, you can set the buffer local value using \\[set-fill-column]. */);
|
||||
|
||||
DEFVAR_PER_BUFFER ("left-margin", ¤t_buffer->left_margin,
|
||||
make_number (Lisp_Int),
|
||||
make_number (LISP_INT_TAG),
|
||||
doc: /* *Column for the default `indent-line-function' to indent to.
|
||||
Linefeed indents to this column in Fundamental mode. */);
|
||||
|
||||
DEFVAR_PER_BUFFER ("tab-width", ¤t_buffer->tab_width,
|
||||
make_number (Lisp_Int),
|
||||
make_number (LISP_INT_TAG),
|
||||
doc: /* *Distance between tab stops (for display of tab characters), in columns. */);
|
||||
|
||||
DEFVAR_PER_BUFFER ("ctl-arrow", ¤t_buffer->ctl_arrow, Qnil,
|
||||
@ -5859,7 +5859,7 @@ If it is nil, that means don't auto-save this buffer. */);
|
||||
Backing up is done before the first time the file is saved. */);
|
||||
|
||||
DEFVAR_PER_BUFFER ("buffer-saved-size", ¤t_buffer->save_length,
|
||||
make_number (Lisp_Int),
|
||||
make_number (LISP_INT_TAG),
|
||||
doc: /* Length of current buffer when last read in, saved or auto-saved.
|
||||
0 initially.
|
||||
-1 means auto-saving turned off until next real save.
|
||||
|
18
src/data.c
18
src/data.c
@ -108,10 +108,12 @@ Lisp_Object
|
||||
wrong_type_argument (predicate, value)
|
||||
register Lisp_Object predicate, value;
|
||||
{
|
||||
/* If VALUE is not even a valid Lisp object, abort here
|
||||
where we can get a backtrace showing where it came from. */
|
||||
if ((unsigned int) XTYPE (value) >= Lisp_Type_Limit)
|
||||
abort ();
|
||||
/* If VALUE is not even a valid Lisp object, we'd want to abort here
|
||||
where we can get a backtrace showing where it came from. We used
|
||||
to try and do that by checking the tagbits, but nowadays all
|
||||
tagbits are potentially valid. */
|
||||
/* if ((unsigned int) XTYPE (value) >= Lisp_Type_Limit)
|
||||
* abort (); */
|
||||
|
||||
xsignal2 (Qwrong_type_argument, predicate, value);
|
||||
}
|
||||
@ -184,7 +186,7 @@ for example, (type-of 1) returns `integer'. */)
|
||||
{
|
||||
switch (XTYPE (object))
|
||||
{
|
||||
case Lisp_Int:
|
||||
case_Lisp_Int:
|
||||
return Qinteger;
|
||||
|
||||
case Lisp_Symbol:
|
||||
@ -975,8 +977,10 @@ store_symval_forwarding (symbol, valcontents, newval, buf)
|
||||
int offset = XBUFFER_OBJFWD (valcontents)->offset;
|
||||
Lisp_Object type = XBUFFER_OBJFWD (valcontents)->slottype;
|
||||
|
||||
if (! NILP (type) && ! NILP (newval)
|
||||
&& XTYPE (newval) != XINT (type))
|
||||
if (!(NILP (type) || NILP (newval)
|
||||
|| (XINT (type) == LISP_INT_TAG
|
||||
? INTEGERP (newval)
|
||||
: XTYPE (newval) == XINT (type))))
|
||||
buffer_slot_type_mismatch (newval, XINT (type));
|
||||
|
||||
if (buf == NULL)
|
||||
|
@ -2267,9 +2267,7 @@ internal_equal (o1, o2, depth, props)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
case Lisp_Int:
|
||||
case Lisp_Symbol:
|
||||
case Lisp_Type_Limit:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4565,7 +4563,7 @@ sxhash (obj, depth)
|
||||
|
||||
switch (XTYPE (obj))
|
||||
{
|
||||
case Lisp_Int:
|
||||
case_Lisp_Int:
|
||||
hash = XUINT (obj);
|
||||
break;
|
||||
|
||||
|
117
src/lisp.h
117
src/lisp.h
@ -150,37 +150,68 @@ extern void die P_((const char *, const char *, int)) NO_RETURN;
|
||||
|
||||
/* Define the fundamental Lisp data structures. */
|
||||
|
||||
/* If USE_2_TAGBITS_FOR_INTS is defined, then Lisp integers use
|
||||
2 tags, to give them one extra bit, thus extending their range from
|
||||
e.g -2^28..2^28-1 to -2^29..2^29-1. */
|
||||
#define USE_2_TAGS_FOR_INTS
|
||||
|
||||
/* Making it work for the union case is too much trouble. */
|
||||
#ifdef USE_LISP_UNION_TYPE
|
||||
# undef USE_2_TAGS_FOR_INTS
|
||||
#endif
|
||||
|
||||
/* This is the set of Lisp data types. */
|
||||
|
||||
#if !defined USE_2_TAGS_FOR_INTS
|
||||
# define LISP_INT_TAG Lisp_Int
|
||||
# define case_Lisp_Int case Lisp_Int
|
||||
# define LISP_STRING_TAG 4
|
||||
# define LISP_INT_TAG_P(x) ((x) == Lisp_Int)
|
||||
#else
|
||||
# define LISP_INT_TAG Lisp_Int0
|
||||
# define case_Lisp_Int case Lisp_Int0: case Lisp_Int1
|
||||
# ifdef USE_LSB_TAG
|
||||
# define LISP_INT1_TAG 4
|
||||
# define LISP_STRING_TAG 1
|
||||
# define LISP_INT_TAG_P(x) (((x) & 3) == 0)
|
||||
# else
|
||||
# define LISP_INT1_TAG 1
|
||||
# define LISP_STRING_TAG 4
|
||||
# define LISP_INT_TAG_P(x) (((x) & 6) == 0)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
enum Lisp_Type
|
||||
{
|
||||
/* Integer. XINT (obj) is the integer value. */
|
||||
Lisp_Int,
|
||||
#ifdef USE_2_TAGS_FOR_INTS
|
||||
Lisp_Int0 = 0,
|
||||
Lisp_Int1 = LISP_INT1_TAG,
|
||||
#else
|
||||
Lisp_Int = 0,
|
||||
#endif
|
||||
|
||||
/* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */
|
||||
Lisp_Symbol,
|
||||
Lisp_Symbol = 2,
|
||||
|
||||
/* Miscellaneous. XMISC (object) points to a union Lisp_Misc,
|
||||
whose first member indicates the subtype. */
|
||||
Lisp_Misc,
|
||||
Lisp_Misc = 3,
|
||||
|
||||
/* String. XSTRING (object) points to a struct Lisp_String.
|
||||
The length of the string, and its contents, are stored therein. */
|
||||
Lisp_String,
|
||||
Lisp_String = LISP_STRING_TAG,
|
||||
|
||||
/* Vector of Lisp objects, or something resembling it.
|
||||
XVECTOR (object) points to a struct Lisp_Vector, which contains
|
||||
the size and contents. The size field also contains the type
|
||||
information, if it's not a real vector object. */
|
||||
Lisp_Vectorlike,
|
||||
Lisp_Vectorlike = 5,
|
||||
|
||||
/* Cons. XCONS (object) points to a struct Lisp_Cons. */
|
||||
Lisp_Cons,
|
||||
Lisp_Cons = 6,
|
||||
|
||||
Lisp_Float,
|
||||
|
||||
/* This is not a type code. It is for range checking. */
|
||||
Lisp_Type_Limit
|
||||
Lisp_Float = 7,
|
||||
};
|
||||
|
||||
/* This is the set of data types that share a common structure.
|
||||
@ -353,12 +384,18 @@ enum pvec_type
|
||||
|
||||
#define TYPEMASK ((((EMACS_INT) 1) << GCTYPEBITS) - 1)
|
||||
#define XTYPE(a) ((enum Lisp_Type) (((EMACS_UINT) (a)) & TYPEMASK))
|
||||
#define XINT(a) (((EMACS_INT) (a)) >> GCTYPEBITS)
|
||||
#define XUINT(a) (((EMACS_UINT) (a)) >> GCTYPEBITS)
|
||||
#ifdef USE_2_TAGS_FOR_INTS
|
||||
# define XINT(a) (((EMACS_INT) (a)) >> (GCTYPEBITS - 1))
|
||||
# define XUINT(a) (((EMACS_UINT) (a)) >> (GCTYPEBITS - 1))
|
||||
# define make_number(N) (((EMACS_INT) (N)) << (GCTYPEBITS - 1))
|
||||
#else
|
||||
# define XINT(a) (((EMACS_INT) (a)) >> GCTYPEBITS)
|
||||
# define XUINT(a) (((EMACS_UINT) (a)) >> GCTYPEBITS)
|
||||
# define make_number(N) (((EMACS_INT) (N)) << GCTYPEBITS)
|
||||
#endif
|
||||
#define XSET(var, type, ptr) \
|
||||
(eassert (XTYPE (ptr) == 0), /* Check alignment. */ \
|
||||
(var) = ((EMACS_INT) (type)) | ((EMACS_INT) (ptr)))
|
||||
#define make_number(N) (((EMACS_INT) (N)) << GCTYPEBITS)
|
||||
|
||||
#define XPNTR(a) ((EMACS_INT) ((a) & ~TYPEMASK))
|
||||
|
||||
@ -378,41 +415,43 @@ enum pvec_type
|
||||
#define XFASTINT(a) ((a) + 0)
|
||||
#define XSETFASTINT(a, b) ((a) = (b))
|
||||
|
||||
/* Extract the value of a Lisp_Object as a signed integer. */
|
||||
/* Extract the value of a Lisp_Object as a (un)signed integer. */
|
||||
|
||||
#ifndef XINT /* Some machines need to do this differently. */
|
||||
#define XINT(a) ((((EMACS_INT) (a)) << (BITS_PER_EMACS_INT - VALBITS)) \
|
||||
#ifdef USE_2_TAGS_FOR_INTS
|
||||
# define XINT(a) ((((EMACS_INT) (a)) << (GCTYPEBITS - 1)) >> (GCTYPEBITS - 1))
|
||||
# define XUINT(a) ((EMACS_UINT) ((a) & (1 + (VALMASK << 1))))
|
||||
# define make_number(N) ((((EMACS_INT) (N)) & (1 + (VALMASK << 1))))
|
||||
#else
|
||||
# define XINT(a) ((((EMACS_INT) (a)) << (BITS_PER_EMACS_INT - VALBITS)) \
|
||||
>> (BITS_PER_EMACS_INT - VALBITS))
|
||||
# define XUINT(a) ((EMACS_UINT) ((a) & VALMASK))
|
||||
# define make_number(N) \
|
||||
((((EMACS_INT) (N)) & VALMASK) | ((EMACS_INT) Lisp_Int) << VALBITS)
|
||||
#endif
|
||||
|
||||
/* Extract the value as an unsigned integer. This is a basis
|
||||
for extracting it as a pointer to a structure in storage. */
|
||||
|
||||
#ifndef XUINT
|
||||
#define XUINT(a) ((EMACS_UINT) ((a) & VALMASK))
|
||||
#endif
|
||||
|
||||
#ifndef XSET
|
||||
#define XSET(var, type, ptr) \
|
||||
((var) = ((EMACS_INT)(type) << VALBITS) + ((EMACS_INT) (ptr) & VALMASK))
|
||||
#endif
|
||||
|
||||
/* Convert a C integer into a Lisp_Object integer. */
|
||||
|
||||
#define make_number(N) \
|
||||
((((EMACS_INT) (N)) & VALMASK) | ((EMACS_INT) Lisp_Int) << VALBITS)
|
||||
#define XPNTR(a) ((EMACS_UINT) ((a) & VALMASK))
|
||||
|
||||
#endif /* not USE_LSB_TAG */
|
||||
|
||||
#else /* USE_LISP_UNION_TYPE */
|
||||
|
||||
#ifdef USE_2_TAGS_FOR_INTS
|
||||
# error "USE_2_TAGS_FOR_INTS is not supported with USE_LISP_UNION_TYPE"
|
||||
#endif
|
||||
|
||||
#define XHASH(a) ((a).i)
|
||||
|
||||
#define XTYPE(a) ((enum Lisp_Type) (a).u.type)
|
||||
|
||||
#ifdef EXPLICIT_SIGN_EXTEND
|
||||
/* Make sure we sign-extend; compilers have been known to fail to do so. */
|
||||
#define XINT(a) (((a).s.val << (BITS_PER_EMACS_INT - VALBITS)) \
|
||||
/* Make sure we sign-extend; compilers have been known to fail to do so.
|
||||
We additionally cast to EMACS_INT since it seems that some compilers
|
||||
have been known to fail to do so, even though the bitfield is declared
|
||||
as EMACS_INT already. */
|
||||
#define XINT(a) ((((EMACS_INT) (a).s.val) << (BITS_PER_EMACS_INT - VALBITS)) \
|
||||
>> (BITS_PER_EMACS_INT - VALBITS))
|
||||
#else
|
||||
#define XINT(a) ((a).s.val)
|
||||
@ -491,11 +530,19 @@ extern size_t pure_size;
|
||||
/* Largest and smallest representable fixnum values. These are the C
|
||||
values. */
|
||||
|
||||
#define MOST_NEGATIVE_FIXNUM - ((EMACS_INT) 1 << (VALBITS - 1))
|
||||
#define MOST_POSITIVE_FIXNUM (((EMACS_INT) 1 << (VALBITS - 1)) - 1)
|
||||
#ifdef USE_2_TAGS_FOR_INTS
|
||||
# define MOST_NEGATIVE_FIXNUM - ((EMACS_INT) 1 << VALBITS)
|
||||
# define MOST_POSITIVE_FIXNUM (((EMACS_INT) 1 << VALBITS) - 1)
|
||||
/* Mask indicating the significant bits of a Lisp_Int.
|
||||
I.e. (x & INTMASK) == XUINT (make_number (x)). */
|
||||
#define INTMASK ((((EMACS_INT) 1) << VALBITS) - 1)
|
||||
# define INTMASK ((((EMACS_INT) 1) << (VALBITS + 1)) - 1)
|
||||
#else
|
||||
# define MOST_NEGATIVE_FIXNUM - ((EMACS_INT) 1 << (VALBITS - 1))
|
||||
# define MOST_POSITIVE_FIXNUM (((EMACS_INT) 1 << (VALBITS - 1)) - 1)
|
||||
/* Mask indicating the significant bits of a Lisp_Int.
|
||||
I.e. (x & INTMASK) == XUINT (make_number (x)). */
|
||||
# define INTMASK ((((EMACS_INT) 1) << VALBITS) - 1)
|
||||
#endif
|
||||
|
||||
/* Value is non-zero if I doesn't fit into a Lisp fixnum. It is
|
||||
written this way so that it also works if I is of unsigned
|
||||
@ -1506,7 +1553,7 @@ typedef struct {
|
||||
#define NUMBERP(x) (INTEGERP (x) || FLOATP (x))
|
||||
#define NATNUMP(x) (INTEGERP (x) && XINT (x) >= 0)
|
||||
|
||||
#define INTEGERP(x) (XTYPE ((x)) == Lisp_Int)
|
||||
#define INTEGERP(x) (LISP_INT_TAG_P (XTYPE ((x))))
|
||||
#define SYMBOLP(x) (XTYPE ((x)) == Lisp_Symbol)
|
||||
#define MISCP(x) (XTYPE ((x)) == Lisp_Misc)
|
||||
#define VECTORLIKEP(x) (XTYPE ((x)) == Lisp_Vectorlike)
|
||||
|
@ -1588,7 +1588,7 @@ print_object (obj, printcharfun, escapeflag)
|
||||
|
||||
switch (XTYPE (obj))
|
||||
{
|
||||
case Lisp_Int:
|
||||
case_Lisp_Int:
|
||||
if (sizeof (int) == sizeof (EMACS_INT))
|
||||
sprintf (buf, "%d", (int) XINT (obj));
|
||||
else if (sizeof (long) == sizeof (EMACS_INT))
|
||||
|
@ -4085,7 +4085,7 @@ face_attr_equal_p (v1, v2)
|
||||
|
||||
return bcmp (SDATA (v1), SDATA (v2), SBYTES (v1)) == 0;
|
||||
|
||||
case Lisp_Int:
|
||||
case_Lisp_Int:
|
||||
case Lisp_Symbol:
|
||||
return 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user