aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2015-01-19 00:56:18 -0800
committerPaul Eggert2015-01-19 01:01:58 -0800
commitb7f83adda5a32140811e8e7decc4394d64cada3d (patch)
tree98d7d6763a62fc033464e4f2d5edde5c937623dd
parent9592a014df784e67a4647d5b6424f2758dfaad3c (diff)
downloademacs-b7f83adda5a32140811e8e7decc4394d64cada3d.tar.gz
emacs-b7f83adda5a32140811e8e7decc4394d64cada3d.zip
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.
-rw-r--r--src/ChangeLog26
-rw-r--r--src/alloc.c6
-rw-r--r--src/callint.c10
-rw-r--r--src/coding.c9
-rw-r--r--src/eval.c11
-rw-r--r--src/fileio.c17
-rw-r--r--src/fns.c13
-rw-r--r--src/font.c7
-rw-r--r--src/fringe.c7
-rw-r--r--src/lisp.h24
10 files changed, 79 insertions, 51 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 16e2fa19626..04b952cae60 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,29 @@
12015-01-19 Paul Eggert <eggert@cs.ucla.edu>
2
3 Prefer memset to repeatedly assigning Qnil
4 * alloc.c (allocate_pseudovector): Catch more bogus values.
5 * alloc.c (allocate_pseudovector):
6 * callint.c (Fcall_interactively):
7 * coding.c (syms_of_coding):
8 * fringe.c (init_fringe):
9 Verify that Qnil == 0.
10 * callint.c (Fcall_interactively):
11 * eval.c (Fapply, Ffuncall):
12 * fns.c (mapcar1, larger_vector):
13 * font.c (font_expand_wildcards):
14 * fringe.c (init_fringe):
15 Prefer memset to assigning zeros by hand.
16 * callint.c (Fcall_interactively):
17 Remove duplicate assignment of Qnil to args[i].
18 * coding.c (syms_of_coding):
19 Prefer LISP_INITIALLY_ZERO to assigning zeros by hand.
20 * fileio.c (Ffile_selinux_context):
21 Rewrite to avoid need for Lisp_Object array.
22 * lisp.h (XLI_BUILTIN_LISPSYM): New macro.
23 (DEFINE_LISP_SYMBOL_END): Use it.
24 (NIL_IS_ZERO): New constant.
25 (memsetnil): New function.
26
12015-01-16 Dmitry Antipov <dmantipov@yandex.ru> 272015-01-16 Dmitry Antipov <dmantipov@yandex.ru>
2 28
3 Tune pseudovector allocation assuming Qnil == 0. 29 Tune pseudovector allocation assuming Qnil == 0.
diff --git a/src/alloc.c b/src/alloc.c
index 22a15b4ac59..2c7b02f1158 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -3169,12 +3169,14 @@ allocate_pseudovector (int memlen, int lisplen,
3169 struct Lisp_Vector *v = allocate_vectorlike (memlen); 3169 struct Lisp_Vector *v = allocate_vectorlike (memlen);
3170 3170
3171 /* Catch bogus values. */ 3171 /* Catch bogus values. */
3172 eassert (tag <= PVEC_FONT); 3172 eassert (0 <= tag && tag <= PVEC_FONT);
3173 eassert (0 <= lisplen && lisplen <= zerolen && zerolen <= memlen);
3173 eassert (memlen - lisplen <= (1 << PSEUDOVECTOR_REST_BITS) - 1); 3174 eassert (memlen - lisplen <= (1 << PSEUDOVECTOR_REST_BITS) - 1);
3174 eassert (lisplen <= (1 << PSEUDOVECTOR_SIZE_BITS) - 1); 3175 eassert (lisplen <= (1 << PSEUDOVECTOR_SIZE_BITS) - 1);
3175 3176
3176 /* Only the first lisplen slots will be traced normally by the GC. 3177 /* Only the first LISPLEN slots will be traced normally by the GC.
3177 But since Qnil == 0, we can memset Lisp_Object slots as well. */ 3178 But since Qnil == 0, we can memset Lisp_Object slots as well. */
3179 verify (NIL_IS_ZERO);
3178 memset (v->contents, 0, zerolen * word_size); 3180 memset (v->contents, 0, zerolen * word_size);
3179 3181
3180 XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen); 3182 XSETPVECTYPESIZE (v, tag, lisplen, memlen - lisplen);
diff --git a/src/callint.c b/src/callint.c
index dd238b976aa..3a595b57d77 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -509,12 +509,8 @@ invoke it. If KEYS is omitted or nil, the return value of
509 visargs = args + nargs; 509 visargs = args + nargs;
510 varies = (signed char *) (visargs + nargs); 510 varies = (signed char *) (visargs + nargs);
511 511
512 for (i = 0; i < nargs; i++) 512 verify (NIL_IS_ZERO);
513 { 513 memset (args, 0, nargs * (2 * word_size + 1));
514 args[i] = Qnil;
515 visargs[i] = Qnil;
516 varies[i] = 0;
517 }
518 514
519 GCPRO5 (prefix_arg, function, *args, *visargs, up_event); 515 GCPRO5 (prefix_arg, function, *args, *visargs, up_event);
520 gcpro3.nvars = nargs; 516 gcpro3.nvars = nargs;
@@ -781,7 +777,7 @@ invoke it. If KEYS is omitted or nil, the return value of
781 argument if no prefix. */ 777 argument if no prefix. */
782 if (NILP (prefix_arg)) 778 if (NILP (prefix_arg))
783 { 779 {
784 args[i] = Qnil; 780 /* args[i] = Qnil; */
785 varies[i] = -1; 781 varies[i] = -1;
786 } 782 }
787 else 783 else
diff --git a/src/coding.c b/src/coding.c
index b11143a32fb..77cea77cef5 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -11272,13 +11272,10 @@ internal character representation. */);
11272 Vtranslation_table_for_input = Qnil; 11272 Vtranslation_table_for_input = Qnil;
11273 11273
11274 { 11274 {
11275 Lisp_Object args[coding_arg_undecided_max]; 11275 verify (NIL_IS_ZERO);
11276 Lisp_Object plist[16]; 11276 Lisp_Object args[coding_arg_undecided_max] = { LISP_INITIALLY_ZERO, };
11277 int i;
11278
11279 for (i = 0; i < coding_arg_undecided_max; i++)
11280 args[i] = Qnil;
11281 11277
11278 Lisp_Object plist[16];
11282 plist[0] = intern_c_string (":name"); 11279 plist[0] = intern_c_string (":name");
11283 plist[1] = args[coding_arg_name] = Qno_conversion; 11280 plist[1] = args[coding_arg_name] = Qno_conversion;
11284 plist[2] = intern_c_string (":mnemonic"); 11281 plist[2] = intern_c_string (":mnemonic");
diff --git a/src/eval.c b/src/eval.c
index 5cadb1bc2de..ddf6535cabc 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2299,8 +2299,7 @@ usage: (apply FUNCTION &rest ARGUMENTS) */)
2299 /* Avoid making funcall cons up a yet another new vector of arguments 2299 /* Avoid making funcall cons up a yet another new vector of arguments
2300 by explicitly supplying nil's for optional values. */ 2300 by explicitly supplying nil's for optional values. */
2301 SAFE_ALLOCA_LISP (funcall_args, 1 + XSUBR (fun)->max_args); 2301 SAFE_ALLOCA_LISP (funcall_args, 1 + XSUBR (fun)->max_args);
2302 for (i = numargs; i < XSUBR (fun)->max_args; /* nothing */) 2302 memsetnil (funcall_args + numargs + 1, XSUBR (fun)->max_args - numargs);
2303 funcall_args[++i] = Qnil;
2304 funcall_nargs = 1 + XSUBR (fun)->max_args; 2303 funcall_nargs = 1 + XSUBR (fun)->max_args;
2305 } 2304 }
2306 else 2305 else
@@ -2638,8 +2637,8 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2638 ptrdiff_t numargs = nargs - 1; 2637 ptrdiff_t numargs = nargs - 1;
2639 Lisp_Object lisp_numargs; 2638 Lisp_Object lisp_numargs;
2640 Lisp_Object val; 2639 Lisp_Object val;
2641 register Lisp_Object *internal_args; 2640 Lisp_Object *internal_args;
2642 ptrdiff_t i, count; 2641 ptrdiff_t count;
2643 2642
2644 QUIT; 2643 QUIT;
2645 2644
@@ -2694,8 +2693,8 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
2694 eassert (XSUBR (fun)->max_args <= ARRAYELTS (internal_argbuf)); 2693 eassert (XSUBR (fun)->max_args <= ARRAYELTS (internal_argbuf));
2695 internal_args = internal_argbuf; 2694 internal_args = internal_argbuf;
2696 memcpy (internal_args, args + 1, numargs * word_size); 2695 memcpy (internal_args, args + 1, numargs * word_size);
2697 for (i = numargs; i < XSUBR (fun)->max_args; i++) 2696 memsetnil (internal_args + numargs,
2698 internal_args[i] = Qnil; 2697 XSUBR (fun)->max_args - numargs);
2699 } 2698 }
2700 else 2699 else
2701 internal_args = args + 1; 2700 internal_args = args + 1;
diff --git a/src/fileio.c b/src/fileio.c
index dc67a00ed2a..ff6720d4ae2 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2812,7 +2812,8 @@ or if SELinux is disabled, or if Emacs lacks SELinux support. */)
2812 (Lisp_Object filename) 2812 (Lisp_Object filename)
2813{ 2813{
2814 Lisp_Object absname; 2814 Lisp_Object absname;
2815 Lisp_Object values[4]; 2815 Lisp_Object user = Qnil, role = Qnil, type = Qnil, range = Qnil;
2816
2816 Lisp_Object handler; 2817 Lisp_Object handler;
2817#if HAVE_LIBSELINUX 2818#if HAVE_LIBSELINUX
2818 security_context_t con; 2819 security_context_t con;
@@ -2830,10 +2831,6 @@ or if SELinux is disabled, or if Emacs lacks SELinux support. */)
2830 2831
2831 absname = ENCODE_FILE (absname); 2832 absname = ENCODE_FILE (absname);
2832 2833
2833 values[0] = Qnil;
2834 values[1] = Qnil;
2835 values[2] = Qnil;
2836 values[3] = Qnil;
2837#if HAVE_LIBSELINUX 2834#if HAVE_LIBSELINUX
2838 if (is_selinux_enabled ()) 2835 if (is_selinux_enabled ())
2839 { 2836 {
@@ -2842,20 +2839,20 @@ or if SELinux is disabled, or if Emacs lacks SELinux support. */)
2842 { 2839 {
2843 context = context_new (con); 2840 context = context_new (con);
2844 if (context_user_get (context)) 2841 if (context_user_get (context))
2845 values[0] = build_string (context_user_get (context)); 2842 user = build_string (context_user_get (context));
2846 if (context_role_get (context)) 2843 if (context_role_get (context))
2847 values[1] = build_string (context_role_get (context)); 2844 role = build_string (context_role_get (context));
2848 if (context_type_get (context)) 2845 if (context_type_get (context))
2849 values[2] = build_string (context_type_get (context)); 2846 type = build_string (context_type_get (context));
2850 if (context_range_get (context)) 2847 if (context_range_get (context))
2851 values[3] = build_string (context_range_get (context)); 2848 range = build_string (context_range_get (context));
2852 context_free (context); 2849 context_free (context);
2853 freecon (con); 2850 freecon (con);
2854 } 2851 }
2855 } 2852 }
2856#endif 2853#endif
2857 2854
2858 return Flist (ARRAYELTS (values), values); 2855 return list4 (user, role, type, range);
2859} 2856}
2860 2857
2861DEFUN ("set-file-selinux-context", Fset_file_selinux_context, 2858DEFUN ("set-file-selinux-context", Fset_file_selinux_context,
diff --git a/src/fns.c b/src/fns.c
index ca3d98b23dd..d177294480a 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -2517,16 +2517,14 @@ usage: (nconc &rest LISTS) */)
2517static void 2517static void
2518mapcar1 (EMACS_INT leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq) 2518mapcar1 (EMACS_INT leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq)
2519{ 2519{
2520 register Lisp_Object tail; 2520 Lisp_Object tail, dummy;
2521 Lisp_Object dummy; 2521 EMACS_INT i;
2522 register EMACS_INT i;
2523 struct gcpro gcpro1, gcpro2, gcpro3; 2522 struct gcpro gcpro1, gcpro2, gcpro3;
2524 2523
2525 if (vals) 2524 if (vals)
2526 { 2525 {
2527 /* Don't let vals contain any garbage when GC happens. */ 2526 /* Don't let vals contain any garbage when GC happens. */
2528 for (i = 0; i < leni; i++) 2527 memsetnil (vals, leni);
2529 vals[i] = Qnil;
2530 2528
2531 GCPRO3 (dummy, fn, seq); 2529 GCPRO3 (dummy, fn, seq);
2532 gcpro1.var = vals; 2530 gcpro1.var = vals;
@@ -3688,7 +3686,7 @@ Lisp_Object
3688larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max) 3686larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
3689{ 3687{
3690 struct Lisp_Vector *v; 3688 struct Lisp_Vector *v;
3691 ptrdiff_t i, incr, incr_max, old_size, new_size; 3689 ptrdiff_t incr, incr_max, old_size, new_size;
3692 ptrdiff_t C_language_max = min (PTRDIFF_MAX, SIZE_MAX) / sizeof *v->contents; 3690 ptrdiff_t C_language_max = min (PTRDIFF_MAX, SIZE_MAX) / sizeof *v->contents;
3693 ptrdiff_t n_max = (0 <= nitems_max && nitems_max < C_language_max 3691 ptrdiff_t n_max = (0 <= nitems_max && nitems_max < C_language_max
3694 ? nitems_max : C_language_max); 3692 ? nitems_max : C_language_max);
@@ -3702,8 +3700,7 @@ larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
3702 new_size = old_size + incr; 3700 new_size = old_size + incr;
3703 v = allocate_vector (new_size); 3701 v = allocate_vector (new_size);
3704 memcpy (v->contents, XVECTOR (vec)->contents, old_size * sizeof *v->contents); 3702 memcpy (v->contents, XVECTOR (vec)->contents, old_size * sizeof *v->contents);
3705 for (i = old_size; i < new_size; ++i) 3703 memsetnil (v->contents + old_size, new_size - old_size);
3706 v->contents[i] = Qnil;
3707 XSETVECTOR (vec, v); 3704 XSETVECTOR (vec, v);
3708 return vec; 3705 return vec;
3709} 3706}
diff --git a/src/font.c b/src/font.c
index 56a27821718..190b33a8ef0 100644
--- a/src/font.c
+++ b/src/font.c
@@ -989,15 +989,14 @@ font_expand_wildcards (Lisp_Object *field, int n)
989 if (i == 0 || ! NILP (tmp[i - 1])) 989 if (i == 0 || ! NILP (tmp[i - 1]))
990 /* None of TMP[X] corresponds to Jth field. */ 990 /* None of TMP[X] corresponds to Jth field. */
991 return -1; 991 return -1;
992 for (; j < range[i].from; j++) 992 memsetnil (field + j, range[i].from - j);
993 field[j] = Qnil; 993 j = range[i].from;
994 } 994 }
995 field[j++] = tmp[i]; 995 field[j++] = tmp[i];
996 } 996 }
997 if (! NILP (tmp[n - 1]) && j < XLFD_REGISTRY_INDEX) 997 if (! NILP (tmp[n - 1]) && j < XLFD_REGISTRY_INDEX)
998 return -1; 998 return -1;
999 for (; j < XLFD_LAST_INDEX; j++) 999 memsetnil (field + j, XLFD_LAST_INDEX - j);
1000 field[j] = Qnil;
1001 if (INTEGERP (field[XLFD_ENCODING_INDEX])) 1000 if (INTEGERP (field[XLFD_ENCODING_INDEX]))
1002 field[XLFD_ENCODING_INDEX] 1001 field[XLFD_ENCODING_INDEX]
1003 = Fintern (Fnumber_to_string (field[XLFD_ENCODING_INDEX]), Qnil); 1002 = Fintern (Fnumber_to_string (field[XLFD_ENCODING_INDEX]), Qnil);
diff --git a/src/fringe.c b/src/fringe.c
index c7262d19336..464379d0cd0 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -1723,15 +1723,12 @@ init_fringe_once (void)
1723void 1723void
1724init_fringe (void) 1724init_fringe (void)
1725{ 1725{
1726 int i;
1727
1728 max_fringe_bitmaps = MAX_STANDARD_FRINGE_BITMAPS + 20; 1726 max_fringe_bitmaps = MAX_STANDARD_FRINGE_BITMAPS + 20;
1729 1727
1730 fringe_bitmaps = xzalloc (max_fringe_bitmaps * sizeof *fringe_bitmaps); 1728 fringe_bitmaps = xzalloc (max_fringe_bitmaps * sizeof *fringe_bitmaps);
1731 fringe_faces = xmalloc (max_fringe_bitmaps * sizeof *fringe_faces);
1732 1729
1733 for (i = 0; i < max_fringe_bitmaps; i++) 1730 verify (NIL_IS_ZERO);
1734 fringe_faces[i] = Qnil; 1731 fringe_faces = xzalloc (max_fringe_bitmaps * sizeof *fringe_faces);
1735} 1732}
1736 1733
1737#ifdef HAVE_NTGUI 1734#ifdef HAVE_NTGUI
diff --git a/src/lisp.h b/src/lisp.h
index 7c7d3f3e2e5..a1ea35574c3 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -732,14 +732,18 @@ struct Lisp_Symbol
732 TAG_PTR (Lisp_Symbol, \ 732 TAG_PTR (Lisp_Symbol, \
733 ((uintptr_t) (offset) >> (USE_LSB_TAG ? 0 : GCTYPEBITS))) 733 ((uintptr_t) (offset) >> (USE_LSB_TAG ? 0 : GCTYPEBITS)))
734 734
735/* XLI_BUILTIN_LISPSYM (iQwhatever) is equivalent to
736 XLI (builtin_lisp_symbol (Qwhatever)),
737 except the former expands to an integer constant expression. */
738#define XLI_BUILTIN_LISPSYM(iname) TAG_SYMOFFSET ((iname) * sizeof *lispsym)
739
735/* Declare extern constants for Lisp symbols. These can be helpful 740/* Declare extern constants for Lisp symbols. These can be helpful
736 when using a debugger like GDB, on older platforms where the debug 741 when using a debugger like GDB, on older platforms where the debug
737 format does not represent C macros. */ 742 format does not represent C macros. */
738#define DEFINE_LISP_SYMBOL_BEGIN(name) \ 743#define DEFINE_LISP_SYMBOL_BEGIN(name) \
739 DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name) 744 DEFINE_GDB_SYMBOL_BEGIN (Lisp_Object, name)
740#define DEFINE_LISP_SYMBOL_END(name) \ 745#define DEFINE_LISP_SYMBOL_END(name) \
741 DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (TAG_SYMOFFSET (i##name \ 746 DEFINE_GDB_SYMBOL_END (LISP_INITIALLY (XLI_BUILTIN_LISPSYM (i##name)))
742 * sizeof *lispsym)))
743 747
744#include "globals.h" 748#include "globals.h"
745 749
@@ -1499,6 +1503,20 @@ gc_aset (Lisp_Object array, ptrdiff_t idx, Lisp_Object val)
1499 XVECTOR (array)->contents[idx] = val; 1503 XVECTOR (array)->contents[idx] = val;
1500} 1504}
1501 1505
1506/* True, since Qnil's representation is zero. Every place in the code
1507 that assumes Qnil is zero should verify (NIL_IS_ZERO), to make it easy
1508 to find such assumptions later if we change Qnil to be nonzero. */
1509enum { NIL_IS_ZERO = XLI_BUILTIN_LISPSYM (iQnil) == 0 };
1510
1511/* Set a Lisp_Object array V's SIZE entries to nil. */
1512INLINE void
1513memsetnil (Lisp_Object *v, ptrdiff_t size)
1514{
1515 eassert (0 <= size);
1516 verify (NIL_IS_ZERO);
1517 memset (v, 0, size * sizeof *v);
1518}
1519
1502/* If a struct is made to look like a vector, this macro returns the length 1520/* If a struct is made to look like a vector, this macro returns the length
1503 of the shortest vector that would hold that struct. */ 1521 of the shortest vector that would hold that struct. */
1504 1522