USE_LSB_TAG not only requires the least 3 bits of pointers returned by
malloc to be 0 but also needs to be able to impose a mult-of-8 alignment
- on the few static Lisp_Objects used: all the defsubr as well
- as the two special buffers buffer_defaults and buffer_local_symbols. */
+ on the few static Lisp_Objects used: lispsym, all the defsubr, and
+ the two special buffers buffer_defaults and buffer_local_symbols. */
enum Lisp_Bits
{
#define lisp_h_XHASH(a) XUINT (a)
#define lisp_h_XPNTR(a) \
(SYMBOLP (a) ? XSYMBOL (a) : (void *) ((intptr_t) (XLI (a) & VALMASK)))
-#define lisp_h_XSYMBOL(a) \
- (eassert (SYMBOLP (a)), \
- (struct Lisp_Symbol *) XUNTAGBASE (a, Lisp_Symbol, lispsym))
#ifndef GC_CHECK_CONS_LIST
# define lisp_h_check_cons_list() ((void) 0)
#endif
XIL ((EMACS_INT) (((EMACS_UINT) (n) << INTTYPEBITS) + Lisp_Int0))
# define lisp_h_XFASTINT(a) XINT (a)
# define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS)
+# define lisp_h_XSYMBOL(a) \
+ (eassert (SYMBOLP (a)), \
+ (struct Lisp_Symbol *) ((uintptr_t) XLI (a) - Lisp_Symbol \
+ + (char *) lispsym))
# define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK))
# define lisp_h_XUNTAG(a, type) ((void *) (intptr_t) (XLI (a) - (type)))
-# define lisp_h_XUNTAGBASE(a, type, base) \
- ((void *) ((char *) (base) - (type) + (intptr_t) XLI (a)))
#endif
/* When compiling via gcc -O0, define the key operations as macros, as
# define XCONS(a) lisp_h_XCONS (a)
# define XHASH(a) lisp_h_XHASH (a)
# define XPNTR(a) lisp_h_XPNTR (a)
-# define XSYMBOL(a) lisp_h_XSYMBOL (a)
# ifndef GC_CHECK_CONS_LIST
# define check_cons_list() lisp_h_check_cons_list ()
# endif
# define make_number(n) lisp_h_make_number (n)
# define XFASTINT(a) lisp_h_XFASTINT (a)
# define XINT(a) lisp_h_XINT (a)
+# define XSYMBOL(a) lisp_h_XSYMBOL (a)
# define XTYPE(a) lisp_h_XTYPE (a)
# define XUNTAG(a, type) lisp_h_XUNTAG (a, type)
-# define XUNTAGBASE(a, type, base) lisp_h_XUNTAGBASE (a, type, base)
# endif
#endif
INLINE bool WINDOWP (Lisp_Object);
INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object);
INLINE struct Lisp_Symbol *(XSYMBOL) (Lisp_Object);
-INLINE void *(XUNTAGBASE) (Lisp_Object, int, void *);
+INLINE enum Lisp_Type (XTYPE) (Lisp_Object);
+INLINE void *(XUNTAG) (Lisp_Object, int);
/* Defined in chartab.c. */
extern Lisp_Object char_table_ref (Lisp_Object, int);
#define TAG_PTR(tag, ptr) \
((USE_LSB_TAG ? (tag) : (EMACS_UINT) (tag) << VALBITS) + (uintptr_t) (ptr))
-/* Yield an integer that tags PTR as a symbol. */
-#define TAG_SYMPTR(ptr) \
- TAG_PTR (Lisp_Symbol, (char *) (ptr) - (char *) (USE_LSB_TAG ? lispsym : 0))
+/* Yield an integer that contains a symbol tag along with OFFSET.
+ OFFSET should be the offset in bytes from 'lispsym' to the symbol. */
+#define TAG_SYMOFFSET(offset) \
+ TAG_PTR (Lisp_Symbol, \
+ ((uintptr_t) (offset) >> (USE_LSB_TAG ? 0 : GCTYPEBITS)))
/* Declare extern constants for Lisp symbols. These can be helpful
when using a debugger like GDB, on older platforms where the debug
- format does not represent C macros. Athough these symbols are
- useless on modern platforms, they don't hurt performance all that much. */
+ format does not represent C macros. */
#define DEFINE_LISP_SYMBOL_BEGIN(name) \
DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name)
#define DEFINE_LISP_SYMBOL_END(name) \
- DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_SYMPTR (name)))
+ DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_SYMOFFSET (i##name \
+ * sizeof *lispsym)))
#include "globals.h"
LISP_MACRO_DEFUN (make_number, Lisp_Object, (EMACS_INT n), (n))
LISP_MACRO_DEFUN (XINT, EMACS_INT, (Lisp_Object a), (a))
LISP_MACRO_DEFUN (XFASTINT, EMACS_INT, (Lisp_Object a), (a))
+LISP_MACRO_DEFUN (XSYMBOL, struct Lisp_Symbol *, (Lisp_Object a), (a))
LISP_MACRO_DEFUN (XTYPE, enum Lisp_Type, (Lisp_Object a), (a))
LISP_MACRO_DEFUN (XUNTAG, void *, (Lisp_Object a, int type), (a, type))
-LISP_MACRO_DEFUN (XUNTAGBASE, void *, (Lisp_Object a, int type, void *base),
- (a, type, base))
#else /* ! USE_LSB_TAG */
return n;
}
+/* Extract A's value as a symbol. */
+INLINE struct Lisp_Symbol *
+XSYMBOL (Lisp_Object a)
+{
+ uintptr_t i = (uintptr_t) XUNTAG (a, Lisp_Symbol);
+ if (! USE_LSB_TAG)
+ i <<= GCTYPEBITS;
+ void *p = (char *) lispsym + i;
+ return p;
+}
+
/* Extract A's type. */
INLINE enum Lisp_Type
XTYPE (Lisp_Object a)
return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS;
}
-/* Extract A's pointer value, assuming A's type is TYPE.
- If USE_LSB_TAG, add BASE to A's pointer value while extracting. */
-INLINE void *
-XUNTAGBASE (Lisp_Object a, int type, void *base)
-{
- char *b = USE_LSB_TAG ? base : 0;
- intptr_t i = USE_LSB_TAG ? XLI (a) - type : XLI (a) & VALMASK;
- return b + i;
-}
-
/* Extract A's pointer value, assuming A's type is TYPE. */
INLINE void *
XUNTAG (Lisp_Object a, int type)
return XUNTAG (a, Lisp_String);
}
-LISP_MACRO_DEFUN (XSYMBOL, struct Lisp_Symbol *, (Lisp_Object a), (a))
-
-/* XSYMBOL_INIT (Qfoo) is like XSYMBOL (Qfoo), except it is valid in
- static initializers, and SYM must be a C-defined symbol. */
-#define XSYMBOL_INIT(sym) a##sym
+/* The index of the C-defined Lisp symbol SYM.
+ This can be used in a static initializer. */
+#define SYMBOL_INDEX(sym) i##sym
INLINE struct Lisp_Float *
XFLOAT (Lisp_Object a)
INLINE Lisp_Object
make_lisp_symbol (struct Lisp_Symbol *sym)
{
- Lisp_Object a = XIL (TAG_SYMPTR (sym));
- eassert (XTYPE (a) == Lisp_Symbol
- && XUNTAGBASE (a, Lisp_Symbol, lispsym) == sym);
+ Lisp_Object a = XIL (TAG_SYMOFFSET ((char *) sym - (char *) lispsym));
+ eassert (XSYMBOL (a) == sym);
return a;
}
+INLINE Lisp_Object
+builtin_lisp_symbol (int index)
+{
+ return make_lisp_symbol (lispsym + index);
+}
+
INLINE Lisp_Object
make_lisp_proc (struct Lisp_Process *p)
{
#define XSETBOOL_VECTOR(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_BOOL_VECTOR))
#define XSETSUB_CHAR_TABLE(a, b) (XSETPSEUDOVECTOR (a, b, PVEC_SUB_CHAR_TABLE))
+/* Efficiently convert a pointer to a Lisp object and back. The
+ pointer is represented as a Lisp integer, so the garbage collector
+ does not know about it. The pointer should not have both Lisp_Int1
+ bits set, which makes this conversion inherently unportable. */
+
+INLINE void *
+XINTPTR (Lisp_Object a)
+{
+ return XUNTAG (a, Lisp_Int0);
+}
+
+INLINE Lisp_Object
+make_pointer_integer (void *p)
+{
+ Lisp_Object a = XIL (TAG_PTR (Lisp_Int0, p));
+ eassert (INTEGERP (a) && XINTPTR (a) == p);
+ return a;
+}
+
/* Type checking. */
LISP_MACRO_DEFUN_VOID (CHECK_TYPE,