/* The IDX==IDX tries to detect when the macro argument is side-effecting. */
#define ASET(ARRAY, IDX, VAL) \
(eassert ((IDX) == (IDX)), \
- eassert ((IDX) >= 0 && (IDX) < (ASIZE (ARRAY) & ~ARRAY_MARK_FLAG)), \
+ eassert ((IDX) >= 0 && (IDX) < ASIZE (ARRAY)), \
XVECTOR (ARRAY)->contents[IDX] = (VAL))
/* Convenience macros for dealing with Lisp strings. */
} next;
};
+/* Regular vector is just a header plus array of Lisp_Objects. */
+
struct Lisp_Vector
{
struct vectorlike_header header;
Lisp_Object contents[1];
};
+/* A boolvector is a kind of vectorlike, with contents are like a string. */
+
+struct Lisp_Bool_Vector
+ {
+ /* HEADER.SIZE is the vector's size field. It doesn't have the real size,
+ just the subtype information. */
+ struct vectorlike_header header;
+ /* This is the size in bits. */
+ EMACS_INT size;
+ /* This contains the actual bits, packed into bytes. */
+ unsigned char data[1];
+ };
+
+/* Some handy constants for calculating sizes
+ and offsets, mostly of vectorlike objects. */
+
+enum
+ {
+ header_size = offsetof (struct Lisp_Vector, contents),
+ bool_header_size = offsetof (struct Lisp_Bool_Vector, data),
+ word_size = sizeof (Lisp_Object)
+ };
+
/* If a struct is made to look like a vector, this macro returns the length
of the shortest vector that would hold that struct. */
-#define VECSIZE(type) ((sizeof (type) \
- - offsetof (struct Lisp_Vector, contents[0]) \
- + sizeof (Lisp_Object) - 1) /* Round up. */ \
- / sizeof (Lisp_Object))
+
+#define VECSIZE(type) \
+ ((sizeof (type) - header_size + word_size - 1) / word_size)
/* Like VECSIZE, but used when the pseudo-vector has non-Lisp_Object fields
at the end and we need to compute the number of Lisp_Object fields (the
ones that the GC needs to trace). */
-#define PSEUDOVECSIZE(type, nonlispfield) \
- ((offsetof (type, nonlispfield) - offsetof (struct Lisp_Vector, contents[0])) \
- / sizeof (Lisp_Object))
+
+#define PSEUDOVECSIZE(type, nonlispfield) \
+ ((offsetof (type, nonlispfield) - header_size) / word_size)
/* A char-table is a kind of vectorlike, with contents are like a
vector but with a few other slots. For some purposes, it makes
Lisp_Object contents[1];
};
-/* A boolvector is a kind of vectorlike, with contents are like a string. */
-struct Lisp_Bool_Vector
- {
- /* HEADER.SIZE is the vector's size field. It doesn't have the real size,
- just the subtype information. */
- struct vectorlike_header header;
- /* This is the size in bits. */
- EMACS_INT size;
- /* This contains the actual bits, packed into bytes. */
- unsigned char data[1];
- };
-
/* This structure describes a built-in function.
It is generated by the DEFUN macro only.
defsubr makes it into a Lisp object.
value gives the ratio of current entries in the hash table and the
size of the hash table. */
-#define DEFAULT_REHASH_THRESHOLD 0.8
+static double const DEFAULT_REHASH_THRESHOLD = 0.8;
/* Default factor by which to increase the size of a hash table. */
-#define DEFAULT_REHASH_SIZE 1.5
+static double const DEFAULT_REHASH_SIZE = 1.5;
/* Most code should use this macro to access
Lisp fields in a different misc objects. */
vchild, and hchild members are all nil. */
#define CHECK_LIVE_WINDOW(x) \
- CHECK_TYPE (WINDOWP (x) && !NILP (WVAR (XWINDOW (x), buffer)), \
+ CHECK_TYPE (WINDOWP (x) && !NILP (WGET (XWINDOW (x), buffer)), \
Qwindow_live_p, x)
#define CHECK_PROCESS(x) \
return & XVECTOR (array)->contents[idx];
}
+LISP_INLINE void
+gc_aset (Lisp_Object array, ptrdiff_t idx, Lisp_Object val)
+{
+ /* Like ASET, but also can be used in the garbage collector:
+ sweep_weak_table calls set_hash_key etc. while the table is marked. */
+ eassert (0 <= idx && idx < (ASIZE (array) & ~ARRAY_MARK_FLAG));
+ XVECTOR (array)->contents[idx] = val;
+}
+
LISP_INLINE void
set_hash_key (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val)
{
- ASET (h->key_and_value, 2 * idx, val);
+ gc_aset (h->key_and_value, 2 * idx, val);
}
LISP_INLINE void
set_hash_value (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val)
{
- ASET (h->key_and_value, 2 * idx + 1, val);
+ gc_aset (h->key_and_value, 2 * idx + 1, val);
}
LISP_INLINE void
set_hash_next (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val)
{
- ASET (h->next, idx, val);
+ gc_aset (h->next, idx, val);
}
LISP_INLINE void
set_hash_hash (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val)
{
- ASET (h->hash, idx, val);
+ gc_aset (h->hash, idx, val);
}
LISP_INLINE void
set_hash_index (struct Lisp_Hash_Table *h, ptrdiff_t idx, Lisp_Object val)
{
- ASET (h->index, idx, val);
+ gc_aset (h->index, idx, val);
}
/* Defined in data.c. */
enum MAX_ALLOCA { MAX_ALLOCA = 16*1024 };
extern Lisp_Object safe_alloca_unwind (Lisp_Object);
+extern void *record_xmalloc (size_t);
#define USE_SAFE_ALLOCA \
ptrdiff_t sa_count = SPECPDL_INDEX (); int sa_must_free = 0
/* SAFE_ALLOCA allocates a simple buffer. */
-#define SAFE_ALLOCA(buf, type, size) \
- do { \
- if ((size) < MAX_ALLOCA) \
- buf = (type) alloca (size); \
- else \
- { \
- buf = xmalloc (size); \
- sa_must_free = 1; \
- record_unwind_protect (safe_alloca_unwind, \
- make_save_value (buf, 0)); \
- } \
- } while (0)
+#define SAFE_ALLOCA(size) ((size) < MAX_ALLOCA \
+ ? alloca (size) \
+ : (sa_must_free = 1, record_xmalloc (size)))
/* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER *
NITEMS items, each of the same type as *BUF. MULTIPLIER must
/* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects. */
-#define SAFE_ALLOCA_LISP(buf, nelt) \
- do { \
- if ((nelt) < MAX_ALLOCA / sizeof (Lisp_Object)) \
- buf = (Lisp_Object *) alloca ((nelt) * sizeof (Lisp_Object)); \
- else if ((nelt) < min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Lisp_Object)) \
- { \
- Lisp_Object arg_; \
- buf = xmalloc ((nelt) * sizeof (Lisp_Object)); \
- arg_ = make_save_value (buf, nelt); \
- XSAVE_VALUE (arg_)->dogc = 1; \
- sa_must_free = 1; \
- record_unwind_protect (safe_alloca_unwind, arg_); \
- } \
- else \
- memory_full (SIZE_MAX); \
+#define SAFE_ALLOCA_LISP(buf, nelt) \
+ do { \
+ if ((nelt) < MAX_ALLOCA / word_size) \
+ buf = alloca ((nelt) * word_size); \
+ else if ((nelt) < min (PTRDIFF_MAX, SIZE_MAX) / word_size) \
+ { \
+ Lisp_Object arg_; \
+ buf = xmalloc ((nelt) * word_size); \
+ arg_ = make_save_value (buf, nelt); \
+ XSAVE_VALUE (arg_)->dogc = 1; \
+ sa_must_free = 1; \
+ record_unwind_protect (safe_alloca_unwind, arg_); \
+ } \
+ else \
+ memory_full (SIZE_MAX); \
} while (0)