changeset 53654:8dc805af6250

[USE_LSB_TAG]: Add definitions for Lisp_Object value manipulation macros for when tags are in the lower bits. (struct Lisp_Free) [USE_LSB_TAG]: Add padding. (DECL_ALIGN): New macro. (DEFUN): Use it.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Wed, 21 Jan 2004 04:31:21 +0000
parents 6f2b0bb10619
children 4f64423a6040
files src/lisp.h
diffstat 1 files changed, 57 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/lisp.h	Wed Jan 21 04:19:21 2004 +0000
+++ b/src/lisp.h	Wed Jan 21 04:31:21 2004 +0000
@@ -289,12 +289,58 @@
 /* For convenience, we also store the number of elements in these bits.  */
 #define PSEUDOVECTOR_SIZE_MASK 0x1ff
 
+/***** Select the tagging scheme.  *****/
+
+/* First, try and define DECL_ALIGN(type,var) which declares a static
+   variable VAR of type TYPE with the added requirement that it be
+   TYPEBITS-aligned. */
+#ifndef DECL_ALIGN
+/* What compiler directive should we use for non-gcc compilers?  -stef  */
+#if defined (__GNUC__)
+#define DECL_ALIGN(type, var) \
+    type __attribute__ ((__aligned__ (1 << GCTYPEBITS))) var
+#endif
+#endif
+
+#ifndef DECL_ALIGN
+/* Can't USE_LSB_TAG if we can't enforce alignment of statically allocated
+   objects like lisp_subr and the special buffers in buffer.c.  */
+#undef USE_LSB_TAG
+#endif
+
+#ifndef USE_LSB_TAG
+/* Just remove the alignment annotation if we don't use it.  */
+#define DECL_ALIGN(type, var) type var
+#endif
+
+
 /* These macros extract various sorts of values from a Lisp_Object.
  For example, if tem is a Lisp_Object whose type is Lisp_Cons,
  XCONS (tem) is the struct Lisp_Cons * pointing to the memory for that cons.  */
 
 #ifdef NO_UNION_TYPE
 
+#ifdef USE_LSB_TAG
+
+#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)
+#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)
+
+/* XFASTINT and XSETFASTINT are for use when the integer is known to be
+   positive, in which case the implementation can sometimes be faster
+   depending on the tagging scheme.  With USE_LSB_TAG, there's no benefit.  */
+#define XFASTINT(a) XINT (a)
+#define XSETFASTINT(a, b) ((a) = make_number (b))
+
+#define XPNTR(a) ((EMACS_INT) ((a) & ~TYPEMASK))
+
+#else  /* not USE_LSB_TAG */
+
 #define VALMASK ((((EMACS_INT) 1) << VALBITS) - 1)
 
 /* One need to override this if there must be high bits set in data space
@@ -333,6 +379,8 @@
 #define make_number(N)		\
   ((((EMACS_INT) (N)) & VALMASK) | ((EMACS_INT) Lisp_Int) << VALBITS)
 
+#endif /* not USE_LSB_TAG */
+
 #define EQ(x, y) ((x) == (y))
 
 #else /* not NO_UNION_TYPE */
@@ -1146,6 +1194,13 @@
     unsigned gcmarkbit : 1;
     int spacer : 15;
     union Lisp_Misc *chain;
+#ifdef USE_LSB_TAG
+    /* Try to make sure that sizeof(Lisp_Misc) preserves TYPEBITS-alignment.
+       This assumes that Lisp_Marker is the largest of the alternatives and
+       that Lisp_Intfwd has the same size as "Lisp_Free w/o padding".  */
+    char padding[((((sizeof (struct Lisp_Marker) - 1) >> GCTYPEBITS) + 1)
+		  << GCTYPEBITS) - sizeof (struct Lisp_Intfwd)];
+#endif
   };
 
 /* To get the type field of a union Lisp_Misc, use XMISCTYPE.
@@ -1513,7 +1568,7 @@
 
 #define DEFUN(lname, fnname, sname, minargs, maxargs, prompt, doc)	\
   Lisp_Object fnname ();						\
-  struct Lisp_Subr sname =						\
+  DECL_ALIGN (struct Lisp_Subr, sname) =				\
     { PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)),	\
       fnname, minargs, maxargs, lname, prompt, 0};			\
   Lisp_Object fnname
@@ -1524,7 +1579,7 @@
    arguments, so we can catch errors with maxargs at compile-time.  */
 #define DEFUN(lname, fnname, sname, minargs, maxargs, prompt, doc)	\
   Lisp_Object fnname DEFUN_ARGS_ ## maxargs ;				\
-  struct Lisp_Subr sname =						\
+  DECL_ALIGN (struct Lisp_Subr, sname) =				\
     { PVEC_SUBR | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)),	\
       fnname, minargs, maxargs, lname, prompt, 0};			\
   Lisp_Object fnname