* alloc.c (allocate_pseudovector): Catch more bogus values.
* alloc.c (allocate_pseudovector):
* callint.c (Fcall_interactively):
* coding.c (syms_of_coding):
* fringe.c (init_fringe):
Verify that Qnil == 0.
* callint.c (Fcall_interactively):
* eval.c (Fapply, Ffuncall):
* fns.c (mapcar1, larger_vector):
* font.c (font_expand_wildcards):
* fringe.c (init_fringe):
Prefer memset to assigning zeros by hand.
* callint.c (Fcall_interactively):
Remove duplicate assignment of Qnil to args[i].
* coding.c (syms_of_coding):
Prefer LISP_INITIALLY_ZERO to assigning zeros by hand.
* fileio.c (Ffile_selinux_context):
Rewrite to avoid need for Lisp_Object array.
* lisp.h (XLI_BUILTIN_LISPSYM): New macro.
(DEFINE_LISP_SYMBOL_END): Use it.
(NIL_IS_ZERO): New constant.
(memsetnil): New function.
+2015-01-19 Paul Eggert <eggert@cs.ucla.edu>
+
+ Prefer memset to repeatedly assigning Qnil
+ * alloc.c (allocate_pseudovector): Catch more bogus values.
+ * alloc.c (allocate_pseudovector):
+ * callint.c (Fcall_interactively):
+ * coding.c (syms_of_coding):
+ * fringe.c (init_fringe):
+ Verify that Qnil == 0.
+ * callint.c (Fcall_interactively):
+ * eval.c (Fapply, Ffuncall):
+ * fns.c (mapcar1, larger_vector):
+ * font.c (font_expand_wildcards):
+ * fringe.c (init_fringe):
+ Prefer memset to assigning zeros by hand.
+ * callint.c (Fcall_interactively):
+ Remove duplicate assignment of Qnil to args[i].
+ * coding.c (syms_of_coding):
+ Prefer LISP_INITIALLY_ZERO to assigning zeros by hand.
+ * fileio.c (Ffile_selinux_context):
+ Rewrite to avoid need for Lisp_Object array.
+ * lisp.h (XLI_BUILTIN_LISPSYM): New macro.
+ (DEFINE_LISP_SYMBOL_END): Use it.
+ (NIL_IS_ZERO): New constant.
+ (memsetnil): New function.
+
2015-01-16 Dmitry Antipov <dmantipov@yandex.ru>
Tune pseudovector allocation assuming Qnil == 0.
struct Lisp_Vector *v = allocate_vectorlike (memlen);
/* Catch bogus values. */
- eassert (tag <= PVEC_FONT);
+ eassert (0 <= tag && tag <= PVEC_FONT);
+ eassert (0 <= lisplen && lisplen <= zerolen && zerolen <= memlen);
eassert (memlen - lisplen <= (1 << PSEUDOVECTOR_REST_BITS) - 1);
eassert (lisplen <= (1 << PSEUDOVECTOR_SIZE_BITS) - 1);
- /* Only the first lisplen slots will be traced normally by the GC.
+ /* Only the first LISPLEN slots will be traced normally by the GC.
But since Qnil == 0, we can memset Lisp_Object slots as well. */
+ verify (NIL_IS_ZERO);
memset (v->contents, 0, zerolen * word_size);
XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen);
visargs = args + nargs;
varies = (signed char *) (visargs + nargs);
- for (i = 0; i < nargs; i++)
- {
- args[i] = Qnil;
- visargs[i] = Qnil;
- varies[i] = 0;
- }
+ verify (NIL_IS_ZERO);
+ memset (args, 0, nargs * (2 * word_size + 1));
GCPRO5 (prefix_arg, function, *args, *visargs, up_event);
gcpro3.nvars = nargs;
argument if no prefix. */
if (NILP (prefix_arg))
{
- args[i] = Qnil;
+ /* args[i] = Qnil; */
varies[i] = -1;
}
else
Vtranslation_table_for_input = Qnil;
{
- Lisp_Object args[coding_arg_undecided_max];
- Lisp_Object plist[16];
- int i;
-
- for (i = 0; i < coding_arg_undecided_max; i++)
- args[i] = Qnil;
+ verify (NIL_IS_ZERO);
+ Lisp_Object args[coding_arg_undecided_max] = { LISP_INITIALLY_ZERO, };
+ Lisp_Object plist[16];
plist[0] = intern_c_string (":name");
plist[1] = args[coding_arg_name] = Qno_conversion;
plist[2] = intern_c_string (":mnemonic");
/* Avoid making funcall cons up a yet another new vector of arguments
by explicitly supplying nil's for optional values. */
SAFE_ALLOCA_LISP (funcall_args, 1 + XSUBR (fun)->max_args);
- for (i = numargs; i < XSUBR (fun)->max_args; /* nothing */)
- funcall_args[++i] = Qnil;
+ memsetnil (funcall_args + numargs + 1, XSUBR (fun)->max_args - numargs);
funcall_nargs = 1 + XSUBR (fun)->max_args;
}
else
ptrdiff_t numargs = nargs - 1;
Lisp_Object lisp_numargs;
Lisp_Object val;
- register Lisp_Object *internal_args;
- ptrdiff_t i, count;
+ Lisp_Object *internal_args;
+ ptrdiff_t count;
QUIT;
eassert (XSUBR (fun)->max_args <= ARRAYELTS (internal_argbuf));
internal_args = internal_argbuf;
memcpy (internal_args, args + 1, numargs * word_size);
- for (i = numargs; i < XSUBR (fun)->max_args; i++)
- internal_args[i] = Qnil;
+ memsetnil (internal_args + numargs,
+ XSUBR (fun)->max_args - numargs);
}
else
internal_args = args + 1;
(Lisp_Object filename)
{
Lisp_Object absname;
- Lisp_Object values[4];
+ Lisp_Object user = Qnil, role = Qnil, type = Qnil, range = Qnil;
+
Lisp_Object handler;
#if HAVE_LIBSELINUX
security_context_t con;
absname = ENCODE_FILE (absname);
- values[0] = Qnil;
- values[1] = Qnil;
- values[2] = Qnil;
- values[3] = Qnil;
#if HAVE_LIBSELINUX
if (is_selinux_enabled ())
{
{
context = context_new (con);
if (context_user_get (context))
- values[0] = build_string (context_user_get (context));
+ user = build_string (context_user_get (context));
if (context_role_get (context))
- values[1] = build_string (context_role_get (context));
+ role = build_string (context_role_get (context));
if (context_type_get (context))
- values[2] = build_string (context_type_get (context));
+ type = build_string (context_type_get (context));
if (context_range_get (context))
- values[3] = build_string (context_range_get (context));
+ range = build_string (context_range_get (context));
context_free (context);
freecon (con);
}
}
#endif
- return Flist (ARRAYELTS (values), values);
+ return list4 (user, role, type, range);
}
\f
DEFUN ("set-file-selinux-context", Fset_file_selinux_context,
static void
mapcar1 (EMACS_INT leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq)
{
- register Lisp_Object tail;
- Lisp_Object dummy;
- register EMACS_INT i;
+ Lisp_Object tail, dummy;
+ EMACS_INT i;
struct gcpro gcpro1, gcpro2, gcpro3;
if (vals)
{
/* Don't let vals contain any garbage when GC happens. */
- for (i = 0; i < leni; i++)
- vals[i] = Qnil;
+ memsetnil (vals, leni);
GCPRO3 (dummy, fn, seq);
gcpro1.var = vals;
larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
{
struct Lisp_Vector *v;
- ptrdiff_t i, incr, incr_max, old_size, new_size;
+ ptrdiff_t incr, incr_max, old_size, new_size;
ptrdiff_t C_language_max = min (PTRDIFF_MAX, SIZE_MAX) / sizeof *v->contents;
ptrdiff_t n_max = (0 <= nitems_max && nitems_max < C_language_max
? nitems_max : C_language_max);
new_size = old_size + incr;
v = allocate_vector (new_size);
memcpy (v->contents, XVECTOR (vec)->contents, old_size * sizeof *v->contents);
- for (i = old_size; i < new_size; ++i)
- v->contents[i] = Qnil;
+ memsetnil (v->contents + old_size, new_size - old_size);
XSETVECTOR (vec, v);
return vec;
}
if (i == 0 || ! NILP (tmp[i - 1]))
/* None of TMP[X] corresponds to Jth field. */
return -1;
- for (; j < range[i].from; j++)
- field[j] = Qnil;
+ memsetnil (field + j, range[i].from - j);
+ j = range[i].from;
}
field[j++] = tmp[i];
}
if (! NILP (tmp[n - 1]) && j < XLFD_REGISTRY_INDEX)
return -1;
- for (; j < XLFD_LAST_INDEX; j++)
- field[j] = Qnil;
+ memsetnil (field + j, XLFD_LAST_INDEX - j);
if (INTEGERP (field[XLFD_ENCODING_INDEX]))
field[XLFD_ENCODING_INDEX]
= Fintern (Fnumber_to_string (field[XLFD_ENCODING_INDEX]), Qnil);
void
init_fringe (void)
{
- int i;
-
max_fringe_bitmaps = MAX_STANDARD_FRINGE_BITMAPS + 20;
fringe_bitmaps = xzalloc (max_fringe_bitmaps * sizeof *fringe_bitmaps);
- fringe_faces = xmalloc (max_fringe_bitmaps * sizeof *fringe_faces);
- for (i = 0; i < max_fringe_bitmaps; i++)
- fringe_faces[i] = Qnil;
+ verify (NIL_IS_ZERO);
+ fringe_faces = xzalloc (max_fringe_bitmaps * sizeof *fringe_faces);
}
#ifdef HAVE_NTGUI
TAG_PTR (Lisp_Symbol, \
((uintptr_t) (offset) >> (USE_LSB_TAG ? 0 : GCTYPEBITS)))
+/* XLI_BUILTIN_LISPSYM (iQwhatever) is equivalent to
+ XLI (builtin_lisp_symbol (Qwhatever)),
+ except the former expands to an integer constant expression. */
+#define XLI_BUILTIN_LISPSYM(iname) TAG_SYMOFFSET ((iname) * sizeof *lispsym)
+
/* 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. */
#define DEFINE_LISP_SYMBOL_BEGIN(name) \
- DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name)
+ DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name)
#define DEFINE_LISP_SYMBOL_END(name) \
- DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_SYMOFFSET (i##name \
- * sizeof *lispsym)))
+ DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (XLI_BUILTIN_LISPSYM (i##name)))
#include "globals.h"
XVECTOR (array)->contents[idx] = val;
}
+/* True, since Qnil's representation is zero. Every place in the code
+ that assumes Qnil is zero should verify (NIL_IS_ZERO), to make it easy
+ to find such assumptions later if we change Qnil to be nonzero. */
+enum { NIL_IS_ZERO = XLI_BUILTIN_LISPSYM (iQnil) == 0 };
+
+/* Set a Lisp_Object array V's SIZE entries to nil. */
+INLINE void
+memsetnil (Lisp_Object *v, ptrdiff_t size)
+{
+ eassert (0 <= size);
+ verify (NIL_IS_ZERO);
+ memset (v, 0, size * sizeof *v);
+}
+
/* If a struct is made to look like a vector, this macro returns the length
of the shortest vector that would hold that struct. */