#include <verify.h>
-#if (defined ENABLE_CHECKING && \
- defined HAVE_VALGRIND_VALGRIND_H && \
- !defined USE_VALGRIND)
+#if (defined ENABLE_CHECKING \
+ && defined HAVE_VALGRIND_VALGRIND_H \
+ && !defined USE_VALGRIND)
# define USE_VALGRIND 1
#endif
#if USE_VALGRIND
#include <valgrind/valgrind.h>
#include <valgrind/memcheck.h>
-static int valgrind_p;
+static bool valgrind_p;
#endif
/* GC_CHECK_MARKED_OBJECTS means do sanity checks on allocated objects.
#define ABLOCKS_BASE(abase) (abase)
#else
#define ABLOCKS_BASE(abase) \
- (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void**)abase)[-1])
+ (1 & (intptr_t) ABLOCKS_BUSY (abase) ? abase : ((void **)abase)[-1])
#endif
/* The list of free ablock. */
aligned = (base == abase);
if (!aligned)
- ((void**)abase)[-1] = base;
+ ((void **) abase)[-1] = base;
#ifdef DOUG_LEA_MALLOC
/* Back to a reasonable maximum of mmap'ed areas. */
(Lisp_Object length, Lisp_Object init)
{
register Lisp_Object val;
- register unsigned char *p, *end;
int c;
EMACS_INT nbytes;
{
nbytes = XINT (length);
val = make_uninit_string (nbytes);
- p = SDATA (val);
- end = p + SCHARS (val);
- while (p != end)
- *p++ = c;
+ memset (SDATA (val), c, nbytes);
+ SDATA (val)[nbytes] = 0;
}
else
{
unsigned char str[MAX_MULTIBYTE_LENGTH];
- int len = CHAR_STRING (c, str);
+ ptrdiff_t len = CHAR_STRING (c, str);
EMACS_INT string_len = XINT (length);
+ unsigned char *p, *beg, *end;
if (string_len > STRING_BYTES_MAX / len)
string_overflow ();
nbytes = len * string_len;
val = make_uninit_multibyte_string (string_len, nbytes);
- p = SDATA (val);
- end = p + nbytes;
- while (p != end)
+ for (beg = SDATA (val), p = beg, end = beg + nbytes; p < end; p += len)
{
- memcpy (p, str, len);
- p += len;
+ /* First time we just copy `str' to the data of `val'. */
+ if (p == beg)
+ memcpy (p, str, len);
+ else
+ {
+ /* Next time we copy largest possible chunk from
+ initialized to uninitialized part of `val'. */
+ len = min (p - beg, end - p);
+ memcpy (p, beg, len);
+ }
}
+ *p = 0;
}
- *p = 0;
return val;
}
verify (sizeof (size_t) * CHAR_BIT == BITS_PER_SIZE_T);
verify ((BITS_PER_SIZE_T & (BITS_PER_SIZE_T - 1)) == 0);
-static
-ptrdiff_t
+static ptrdiff_t
bool_vector_payload_bytes (ptrdiff_t nr_bits,
- ptrdiff_t* exact_needed_bytes_out)
+ ptrdiff_t *exact_needed_bytes_out)
{
ptrdiff_t exact_needed_bytes;
ptrdiff_t needed_bytes;
- eassert_and_assume (nr_bits >= 0);
+ eassert (nr_bits >= 0);
exact_needed_bytes = ROUNDUP ((size_t) nr_bits, CHAR_BIT) / CHAR_BIT;
needed_bytes = ROUNDUP ((size_t) nr_bits, BITS_PER_SIZE_T) / CHAR_BIT;
total_payload_bytes = bool_vector_payload_bytes
(XFASTINT (length), &exact_payload_bytes);
- eassert_and_assume (exact_payload_bytes <= total_payload_bytes);
- eassert_and_assume (0 <= exact_payload_bytes);
+ eassert (exact_payload_bytes <= total_payload_bytes);
+ eassert (0 <= exact_payload_bytes);
needed_elements = ROUNDUP ((size_t) ((bool_header_size - header_size)
+ total_payload_bytes),
word_size) / word_size;
- p = (struct Lisp_Bool_Vector* ) allocate_vector (needed_elements);
+ p = (struct Lisp_Bool_Vector *) allocate_vector (needed_elements);
XSETVECTOR (val, p);
XSETPVECTYPESIZE (XVECTOR (val), PVEC_BOOL_VECTOR, 0, 0);
verify (VECTOR_BLOCK_SIZE <= (1 << PSEUDOVECTOR_SIZE_BITS));
/* Round up X to nearest mult-of-ROUNDUP_SIZE --- use at compile time. */
-#define vroundup_ct(x) ROUNDUP((size_t)(x), roundup_size)
+#define vroundup_ct(x) ROUNDUP ((size_t) (x), roundup_size)
/* Round up X to nearest mult-of-ROUNDUP_SIZE --- use at runtime. */
-#define vroundup(x) (assume((x) >= 0), vroundup_ct(x))
+#define vroundup(x) (assume ((x) >= 0), vroundup_ct (x))
/* Rounding helps to maintain alignment constraints if USE_LSB_TAG. */
#define VINDEX(nbytes) (((nbytes) - VBLOCK_BYTES_MIN) / roundup_size)
-/* Get and set the next field in block-allocated vectorlike objects on
- the free list. Doing it this way respects C's aliasing rules.
- We could instead make 'contents' a union, but that would mean
- changes everywhere that the code uses 'contents'. */
-static struct Lisp_Vector *
-next_in_free_list (struct Lisp_Vector *v)
-{
- intptr_t i = XLI (v->contents[0]);
- return (struct Lisp_Vector *) i;
-}
-static void
-set_next_in_free_list (struct Lisp_Vector *v, struct Lisp_Vector *next)
-{
- v->contents[0] = XIL ((intptr_t) next);
-}
-
/* Common shortcut to setup vector on a free list. */
#define SETUP_ON_FREE_LIST(v, nbytes, tmp) \
eassert ((nbytes) % roundup_size == 0); \
(tmp) = VINDEX (nbytes); \
eassert ((tmp) < VECTOR_MAX_FREE_LIST_INDEX); \
- set_next_in_free_list (v, vector_free_lists[tmp]); \
+ v->u.next = vector_free_lists[tmp]; \
vector_free_lists[tmp] = (v); \
total_free_vector_slots += (nbytes) / word_size; \
} while (0)
if (vector_free_lists[index])
{
vector = vector_free_lists[index];
- vector_free_lists[index] = next_in_free_list (vector);
+ vector_free_lists[index] = vector->u.next;
total_free_vector_slots -= nbytes / word_size;
return vector;
}
{
/* This vector is larger than requested. */
vector = vector_free_lists[index];
- vector_free_lists[index] = next_in_free_list (vector);
+ vector_free_lists[index] = vector->u.next;
total_free_vector_slots -= nbytes / word_size;
/* Excess bytes are used for the smaller vector,
ptrdiff_t payload_bytes =
bool_vector_payload_bytes (bv->size, NULL);
- eassert_and_assume (payload_bytes >= 0);
+ eassert (payload_bytes >= 0);
size = bool_header_size + ROUNDUP (payload_bytes, word_size);
}
else
free_this_block = 1;
else
{
- int tmp;
+ size_t tmp;
SETUP_ON_FREE_LIST (vector, total_bytes, tmp);
}
}
else
{
struct large_vector *lv
- = lisp_malloc ((offsetof (struct large_vector, v.contents)
+ = lisp_malloc ((offsetof (struct large_vector, v.u.contents)
+ len * word_size),
MEM_TYPE_VECTORLIKE);
lv->next.vector = large_vectors;
/* Only the first lisplen slots will be traced normally by the GC. */
for (i = 0; i < lisplen; ++i)
- v->contents[i] = Qnil;
+ v->u.contents[i] = Qnil;
XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen);
return v;
p = allocate_vector (XFASTINT (length));
sizei = XFASTINT (length);
for (i = 0; i < sizei; i++)
- p->contents[i] = init;
+ p->u.contents[i] = init;
XSETVECTOR (vector, p);
return vector;
register struct Lisp_Vector *p = XVECTOR (val);
for (i = 0; i < nargs; i++)
- p->contents[i] = args[i];
+ p->u.contents[i] = args[i];
return val;
}
void
make_byte_code (struct Lisp_Vector *v)
{
- if (v->header.size > 1 && STRINGP (v->contents[1])
- && STRING_MULTIBYTE (v->contents[1]))
+ /* Don't allow the global zero_vector to become a byte code object. */
+ eassert(0 < v->header.size);
+ if (v->header.size > 1 && STRINGP (v->u.contents[1])
+ && STRING_MULTIBYTE (v->u.contents[1]))
/* BYTECODE-STRING must have been produced by Emacs 20.2 or the
earlier because they produced a raw 8-bit string for byte-code
and now such a byte-code string is loaded as multibyte while
raw 8-bit characters converted to multibyte form. Thus, now we
must convert them back to the original unibyte form. */
- v->contents[1] = Fstring_as_unibyte (v->contents[1]);
+ v->u.contents[1] = Fstring_as_unibyte (v->u.contents[1]);
XSETPVECTYPE (v, PVEC_COMPILED);
}
to be setcar'd). */
for (i = 0; i < nargs; i++)
- p->contents[i] = args[i];
+ p->u.contents[i] = args[i];
make_byte_code (p);
XSETCOMPILED (val, p);
return val;
if (emacs_pipe (fd) == 0)
{
- bool valid = emacs_write (fd[1], (char *) p, 16) == 16;
+ bool valid = emacs_write (fd[1], p, 16) == 16;
emacs_close (fd[1]);
emacs_close (fd[0]);
return valid;
size &= PSEUDOVECTOR_SIZE_MASK;
vec = XVECTOR (make_pure_vector (size));
for (i = 0; i < size; i++)
- vec->contents[i] = Fpurecopy (AREF (obj, i));
+ vec->u.contents[i] = Fpurecopy (AREF (obj, i));
if (COMPILEDP (obj))
{
XSETPVECTYPE (vec, PVEC_COMPILED);
mark_object (tail->var[i]);
}
mark_byte_stack ();
+#endif
{
- struct catchtag *catch;
struct handler *handler;
-
- for (catch = catchlist; catch; catch = catch->next)
- {
- mark_object (catch->tag);
- mark_object (catch->val);
- }
- for (handler = handlerlist; handler; handler = handler->next)
- {
- mark_object (handler->handler);
- mark_object (handler->var);
- }
+ for (handler = handlerlist; handler; handler = handler->next)
+ {
+ mark_object (handler->tag_or_ch);
+ mark_object (handler->val);
+ }
}
-#endif
-
#ifdef HAVE_WINDOW_SYSTEM
mark_fringe_data ();
#endif
The distinction is used e.g. by Lisp_Process which places extra
non-Lisp_Object fields at the end of the structure... */
for (i = 0; i < size; i++) /* ...and then mark its elements. */
- mark_object (ptr->contents[i]);
+ mark_object (ptr->u.contents[i]);
}
/* Like mark_vectorlike but optimized for char-tables (and
VECTOR_MARK (ptr);
for (i = 0; i < size; i++)
{
- Lisp_Object val = ptr->contents[i];
+ Lisp_Object val = ptr->u.contents[i];
if (INTEGERP (val) || (SYMBOLP (val) && XSYMBOL (val)->gcmarkbit))
continue;
VECTOR_MARK (ptr);
for (i = 0; i < size; i++)
if (i != COMPILED_CONSTANTS)
- mark_object (ptr->contents[i]);
+ mark_object (ptr->u.contents[i]);
if (size > COMPILED_CONSTANTS)
{
- obj = ptr->contents[COMPILED_CONSTANTS];
+ obj = ptr->u.contents[COMPILED_CONSTANTS];
goto loop;
}
}
gcs_done = 0;
#if USE_VALGRIND
- valgrind_p = RUNNING_ON_VALGRIND;
+ valgrind_p = RUNNING_ON_VALGRIND != 0;
#endif
}