aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2019-01-09 09:52:38 -0800
committerPaul Eggert2019-01-09 09:59:10 -0800
commita84650334e30b2451bf4a8957bf2d57ade296d4e (patch)
treeb5642bb98eb89733def116fb6d864f74855023e2 /src
parentf9d0fd6c1953138f7473a22917a1508740b2ce40 (diff)
downloademacs-a84650334e30b2451bf4a8957bf2d57ade296d4e.tar.gz
emacs-a84650334e30b2451bf4a8957bf2d57ade296d4e.zip
Use shortcuts for Flength
When calculating the length of a Lisp object whose type is known, use a specialized length operation on it to save a bit of runtime overhead. * src/callint.c (Fcall_interactively): * src/minibuf.c (read_minibuf_unwind): Use ASIZE rather than Flength on values that must be vectors. * src/charset.c (Fsort_charsets): * src/coding.c (detect_coding_sjis): (Fdefine_coding_system_internal): * src/data.c (wrong_choice): * src/eval.c (Flet, eval_sub, Fapply, apply_lambda): * src/fns.c (sort_list): * src/font.c (font_vconcat_entity_vectors) (font_find_for_lface): * src/frame.c (Fmodify_frame_parameters): * src/fringe.c (get_logical_fringe_bitmap): * src/ftfont.c (ftfont_get_open_type_spec): * src/gtkutil.c (xg_print_frames_dialog): * src/lread.c (read1, read_vector): * src/keymap.c (Fkey_description): * src/kqueue.c (Fkqueue_add_watch): * src/macfont.m (macfont_get_open_type_spec): * src/menu.c (parse_single_submenu, x_popup_menu_1): * src/minibuf.c (Finternal_complete_buffer): * src/nsfont.m (ns_findfonts, nsfont_list_family): * src/process.c (Fmake_process): * src/search.c (Fset_match_data): * src/xfaces.c (Fx_family_fonts): Use list_length rather than Flength on values that must be lists. * src/fns.c (list_length): New function. (Flength): Use it. * src/nsfont.m (ns_findfonts): Use !NILP (x) rather than XFIXNUM (Flength (x)) != 0. * src/xdisp.c (store_mode_line_string): Use SCHARS rather than Flength on values that must be strings.
Diffstat (limited to 'src')
-rw-r--r--src/callint.c2
-rw-r--r--src/charset.c3
-rw-r--r--src/coding.c14
-rw-r--r--src/data.c8
-rw-r--r--src/eval.c48
-rw-r--r--src/fns.c61
-rw-r--r--src/font.c7
-rw-r--r--src/frame.c2
-rw-r--r--src/fringe.c6
-rw-r--r--src/ftfont.c8
-rw-r--r--src/gtkutil.c2
-rw-r--r--src/keymap.c2
-rw-r--r--src/kqueue.c5
-rw-r--r--src/lisp.h1
-rw-r--r--src/lread.c5
-rw-r--r--src/macfont.m8
-rw-r--r--src/menu.c12
-rw-r--r--src/minibuf.c5
-rw-r--r--src/nsfont.m10
-rw-r--r--src/process.c4
-rw-r--r--src/search.c4
-rw-r--r--src/xdisp.c2
-rw-r--r--src/xfaces.c3
23 files changed, 98 insertions, 124 deletions
diff --git a/src/callint.c b/src/callint.c
index dac905e16f4..0911c49ae59 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -572,7 +572,7 @@ invoke it. If KEYS is omitted or nil, the return value of
572 /* If the key sequence ends with a down-event, 572 /* If the key sequence ends with a down-event,
573 discard the following up-event. */ 573 discard the following up-event. */
574 Lisp_Object teml 574 Lisp_Object teml
575 = Faref (args[i], make_fixnum (XFIXNUM (Flength (args[i])) - 1)); 575 = Faref (args[i], make_fixnum (ASIZE (args[i]) - 1));
576 if (CONSP (teml)) 576 if (CONSP (teml))
577 teml = XCAR (teml); 577 teml = XCAR (teml);
578 if (SYMBOLP (teml)) 578 if (SYMBOLP (teml))
diff --git a/src/charset.c b/src/charset.c
index 427349b298a..724b35536ed 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -2242,8 +2242,7 @@ Return the sorted list. CHARSETS is modified by side effects.
2242See also `charset-priority-list' and `set-charset-priority'. */) 2242See also `charset-priority-list' and `set-charset-priority'. */)
2243 (Lisp_Object charsets) 2243 (Lisp_Object charsets)
2244{ 2244{
2245 Lisp_Object len = Flength (charsets); 2245 ptrdiff_t n = list_length (charsets), i, j;
2246 ptrdiff_t n = XFIXNAT (len), i, j;
2247 int done; 2246 int done;
2248 Lisp_Object tail, elt, attrs; 2247 Lisp_Object tail, elt, attrs;
2249 struct charset_sort_data *sort_data; 2248 struct charset_sort_data *sort_data;
diff --git a/src/coding.c b/src/coding.c
index 0297c8a100d..1c1462198ca 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -4591,8 +4591,7 @@ detect_coding_sjis (struct coding_system *coding,
4591 int max_first_byte_of_2_byte_code; 4591 int max_first_byte_of_2_byte_code;
4592 4592
4593 CODING_GET_INFO (coding, attrs, charset_list); 4593 CODING_GET_INFO (coding, attrs, charset_list);
4594 max_first_byte_of_2_byte_code 4594 max_first_byte_of_2_byte_code = list_length (charset_list) <= 3 ? 0xEF : 0xFC;
4595 = (XFIXNUM (Flength (charset_list)) > 3 ? 0xFC : 0xEF);
4596 4595
4597 detect_info->checked |= CATEGORY_MASK_SJIS; 4596 detect_info->checked |= CATEGORY_MASK_SJIS;
4598 /* A coding system of this category is always ASCII compatible. */ 4597 /* A coding system of this category is always ASCII compatible. */
@@ -10387,14 +10386,11 @@ usage: (define-coding-system-internal ...) */)
10387 } 10386 }
10388 else if (EQ (coding_type, Qshift_jis)) 10387 else if (EQ (coding_type, Qshift_jis))
10389 { 10388 {
10390 10389 ptrdiff_t charset_list_len = list_length (charset_list);
10391 struct charset *charset; 10390 if (charset_list_len != 3 && charset_list_len != 4)
10392
10393 if (XFIXNUM (Flength (charset_list)) != 3
10394 && XFIXNUM (Flength (charset_list)) != 4)
10395 error ("There should be three or four charsets"); 10391 error ("There should be three or four charsets");
10396 10392
10397 charset = CHARSET_FROM_ID (XFIXNUM (XCAR (charset_list))); 10393 struct charset *charset = CHARSET_FROM_ID (XFIXNUM (XCAR (charset_list)));
10398 if (CHARSET_DIMENSION (charset) != 1) 10394 if (CHARSET_DIMENSION (charset) != 1)
10399 error ("Dimension of charset %s is not one", 10395 error ("Dimension of charset %s is not one",
10400 SDATA (SYMBOL_NAME (CHARSET_NAME (charset)))); 10396 SDATA (SYMBOL_NAME (CHARSET_NAME (charset))));
@@ -10429,7 +10425,7 @@ usage: (define-coding-system-internal ...) */)
10429 { 10425 {
10430 struct charset *charset; 10426 struct charset *charset;
10431 10427
10432 if (XFIXNUM (Flength (charset_list)) != 2) 10428 if (list_length (charset_list) != 2)
10433 error ("There should be just two charsets"); 10429 error ("There should be just two charsets");
10434 10430
10435 charset = CHARSET_FROM_ID (XFIXNUM (XCAR (charset_list))); 10431 charset = CHARSET_FROM_ID (XFIXNUM (XCAR (charset_list)));
diff --git a/src/data.c b/src/data.c
index 1c124740815..a9908a34f4f 100644
--- a/src/data.c
+++ b/src/data.c
@@ -980,14 +980,12 @@ chain of aliases, signal a `cyclic-variable-indirection' error. */)
980 swap_in_symval_forwarding for that. */ 980 swap_in_symval_forwarding for that. */
981 981
982Lisp_Object 982Lisp_Object
983do_symval_forwarding (register union Lisp_Fwd *valcontents) 983do_symval_forwarding (union Lisp_Fwd *valcontents)
984{ 984{
985 register Lisp_Object val;
986 switch (XFWDTYPE (valcontents)) 985 switch (XFWDTYPE (valcontents))
987 { 986 {
988 case Lisp_Fwd_Int: 987 case Lisp_Fwd_Int:
989 XSETINT (val, *XFIXNUMFWD (valcontents)->intvar); 988 return make_fixnum (*XFIXNUMFWD (valcontents)->intvar);
990 return val;
991 989
992 case Lisp_Fwd_Bool: 990 case Lisp_Fwd_Bool:
993 return (*XBOOLFWD (valcontents)->boolvar ? Qt : Qnil); 991 return (*XBOOLFWD (valcontents)->boolvar ? Qt : Qnil);
@@ -1023,7 +1021,7 @@ do_symval_forwarding (register union Lisp_Fwd *valcontents)
1023void 1021void
1024wrong_choice (Lisp_Object choice, Lisp_Object wrong) 1022wrong_choice (Lisp_Object choice, Lisp_Object wrong)
1025{ 1023{
1026 ptrdiff_t i = 0, len = XFIXNUM (Flength (choice)); 1024 ptrdiff_t i = 0, len = list_length (choice);
1027 Lisp_Object obj, *args; 1025 Lisp_Object obj, *args;
1028 AUTO_STRING (one_of, "One of "); 1026 AUTO_STRING (one_of, "One of ");
1029 AUTO_STRING (comma, ", "); 1027 AUTO_STRING (comma, ", ");
diff --git a/src/eval.c b/src/eval.c
index c64a40b955d..28478956e35 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -951,16 +951,15 @@ usage: (let VARLIST BODY...) */)
951 (Lisp_Object args) 951 (Lisp_Object args)
952{ 952{
953 Lisp_Object *temps, tem, lexenv; 953 Lisp_Object *temps, tem, lexenv;
954 Lisp_Object elt, varlist; 954 Lisp_Object elt;
955 ptrdiff_t count = SPECPDL_INDEX (); 955 ptrdiff_t count = SPECPDL_INDEX ();
956 ptrdiff_t argnum; 956 ptrdiff_t argnum;
957 USE_SAFE_ALLOCA; 957 USE_SAFE_ALLOCA;
958 958
959 varlist = XCAR (args); 959 Lisp_Object varlist = XCAR (args);
960 CHECK_LIST (varlist);
961 960
962 /* Make space to hold the values to give the bound variables. */ 961 /* Make space to hold the values to give the bound variables. */
963 EMACS_INT varlist_len = XFIXNAT (Flength (varlist)); 962 EMACS_INT varlist_len = list_length (varlist);
964 SAFE_ALLOCA_LISP (temps, varlist_len); 963 SAFE_ALLOCA_LISP (temps, varlist_len);
965 ptrdiff_t nvars = varlist_len; 964 ptrdiff_t nvars = varlist_len;
966 965
@@ -2263,14 +2262,15 @@ eval_sub (Lisp_Object form)
2263 if (SUBRP (fun)) 2262 if (SUBRP (fun))
2264 { 2263 {
2265 Lisp_Object args_left = original_args; 2264 Lisp_Object args_left = original_args;
2266 Lisp_Object numargs = Flength (args_left); 2265 ptrdiff_t numargs = list_length (args_left);
2267 2266
2268 check_cons_list (); 2267 check_cons_list ();
2269 2268
2270 if (XFIXNUM (numargs) < XSUBR (fun)->min_args 2269 if (numargs < XSUBR (fun)->min_args
2271 || (XSUBR (fun)->max_args >= 0 2270 || (XSUBR (fun)->max_args >= 0
2272 && XSUBR (fun)->max_args < XFIXNUM (numargs))) 2271 && XSUBR (fun)->max_args < numargs))
2273 xsignal2 (Qwrong_number_of_arguments, original_fun, numargs); 2272 xsignal2 (Qwrong_number_of_arguments, original_fun,
2273 make_fixnum (numargs));
2274 2274
2275 else if (XSUBR (fun)->max_args == UNEVALLED) 2275 else if (XSUBR (fun)->max_args == UNEVALLED)
2276 val = (XSUBR (fun)->function.aUNEVALLED) (args_left); 2276 val = (XSUBR (fun)->function.aUNEVALLED) (args_left);
@@ -2281,9 +2281,9 @@ eval_sub (Lisp_Object form)
2281 ptrdiff_t argnum = 0; 2281 ptrdiff_t argnum = 0;
2282 USE_SAFE_ALLOCA; 2282 USE_SAFE_ALLOCA;
2283 2283
2284 SAFE_ALLOCA_LISP (vals, XFIXNUM (numargs)); 2284 SAFE_ALLOCA_LISP (vals, numargs);
2285 2285
2286 while (CONSP (args_left) && argnum < XFIXNUM (numargs)) 2286 while (CONSP (args_left) && argnum < numargs)
2287 { 2287 {
2288 Lisp_Object arg = XCAR (args_left); 2288 Lisp_Object arg = XCAR (args_left);
2289 args_left = XCDR (args_left); 2289 args_left = XCDR (args_left);
@@ -2313,7 +2313,7 @@ eval_sub (Lisp_Object form)
2313 args_left = Fcdr (args_left); 2313 args_left = Fcdr (args_left);
2314 } 2314 }
2315 2315
2316 set_backtrace_args (specpdl + count, argvals, XFIXNUM (numargs)); 2316 set_backtrace_args (specpdl + count, argvals, numargs);
2317 2317
2318 switch (i) 2318 switch (i)
2319 { 2319 {
@@ -2417,16 +2417,13 @@ Thus, (apply \\='+ 1 2 \\='(3 4)) returns 10.
2417usage: (apply FUNCTION &rest ARGUMENTS) */) 2417usage: (apply FUNCTION &rest ARGUMENTS) */)
2418 (ptrdiff_t nargs, Lisp_Object *args) 2418 (ptrdiff_t nargs, Lisp_Object *args)
2419{ 2419{
2420 ptrdiff_t i, numargs, funcall_nargs; 2420 ptrdiff_t i, funcall_nargs;
2421 register Lisp_Object *funcall_args = NULL; 2421 Lisp_Object *funcall_args = NULL;
2422 register Lisp_Object spread_arg = args[nargs - 1]; 2422 Lisp_Object spread_arg = args[nargs - 1];
2423 Lisp_Object fun = args[0]; 2423 Lisp_Object fun = args[0];
2424 Lisp_Object retval;
2425 USE_SAFE_ALLOCA; 2424 USE_SAFE_ALLOCA;
2426 2425
2427 CHECK_LIST (spread_arg); 2426 ptrdiff_t numargs = list_length (spread_arg);
2428
2429 numargs = XFIXNUM (Flength (spread_arg));
2430 2427
2431 if (numargs == 0) 2428 if (numargs == 0)
2432 return Ffuncall (nargs - 1, args); 2429 return Ffuncall (nargs - 1, args);
@@ -2476,7 +2473,7 @@ usage: (apply FUNCTION &rest ARGUMENTS) */)
2476 spread_arg = XCDR (spread_arg); 2473 spread_arg = XCDR (spread_arg);
2477 } 2474 }
2478 2475
2479 retval = Ffuncall (funcall_nargs, funcall_args); 2476 Lisp_Object retval = Ffuncall (funcall_nargs, funcall_args);
2480 2477
2481 SAFE_FREE (); 2478 SAFE_FREE ();
2482 return retval; 2479 return retval;
@@ -2974,25 +2971,22 @@ funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args)
2974static Lisp_Object 2971static Lisp_Object
2975apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count) 2972apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count)
2976{ 2973{
2977 Lisp_Object args_left;
2978 ptrdiff_t i;
2979 EMACS_INT numargs;
2980 Lisp_Object *arg_vector; 2974 Lisp_Object *arg_vector;
2981 Lisp_Object tem; 2975 Lisp_Object tem;
2982 USE_SAFE_ALLOCA; 2976 USE_SAFE_ALLOCA;
2983 2977
2984 numargs = XFIXNAT (Flength (args)); 2978 ptrdiff_t numargs = list_length (args);
2985 SAFE_ALLOCA_LISP (arg_vector, numargs); 2979 SAFE_ALLOCA_LISP (arg_vector, numargs);
2986 args_left = args; 2980 Lisp_Object args_left = args;
2987 2981
2988 for (i = 0; i < numargs; ) 2982 for (ptrdiff_t i = 0; i < numargs; i++)
2989 { 2983 {
2990 tem = Fcar (args_left), args_left = Fcdr (args_left); 2984 tem = Fcar (args_left), args_left = Fcdr (args_left);
2991 tem = eval_sub (tem); 2985 tem = eval_sub (tem);
2992 arg_vector[i++] = tem; 2986 arg_vector[i] = tem;
2993 } 2987 }
2994 2988
2995 set_backtrace_args (specpdl + count, arg_vector, i); 2989 set_backtrace_args (specpdl + count, arg_vector, numargs);
2996 tem = funcall_lambda (fun, numargs, arg_vector); 2990 tem = funcall_lambda (fun, numargs, arg_vector);
2997 2991
2998 check_cons_list (); 2992 check_cons_list ();
diff --git a/src/fns.c b/src/fns.c
index 7791310a313..0fad6f47447 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -91,42 +91,50 @@ See Info node `(elisp)Random Numbers' for more details. */)
91 91
92/* Random data-structure functions. */ 92/* Random data-structure functions. */
93 93
94/* Return the length of LIST. Signal an error if LIST is not a proper
95 list or if the length does not fit into a fixnum or into ptrdiff_t. */
96
97ptrdiff_t
98list_length (Lisp_Object list)
99{
100 intptr_t i = 0;
101 FOR_EACH_TAIL (list)
102 i++;
103 CHECK_LIST_END (list, list);
104 if (i <= min (PTRDIFF_MAX, MOST_POSITIVE_FIXNUM))
105 return i;
106 overflow_error ();
107}
108
109
94DEFUN ("length", Flength, Slength, 1, 1, 0, 110DEFUN ("length", Flength, Slength, 1, 1, 0,
95 doc: /* Return the length of vector, list or string SEQUENCE. 111 doc: /* Return the length of vector, list or string SEQUENCE.
96A byte-code function object is also allowed. 112A byte-code function object is also allowed.
97If the string contains multibyte characters, this is not necessarily 113If the string contains multibyte characters, this is not necessarily
98the number of bytes in the string; it is the number of characters. 114the number of bytes in the string; it is the number of characters.
99To get the number of bytes, use `string-bytes'. */) 115To get the number of bytes, use `string-bytes'. */)
100 (register Lisp_Object sequence) 116 (Lisp_Object sequence)
101{ 117{
102 register Lisp_Object val; 118 EMACS_INT val;
103 119
104 if (STRINGP (sequence)) 120 if (STRINGP (sequence))
105 XSETFASTINT (val, SCHARS (sequence)); 121 val = SCHARS (sequence);
106 else if (VECTORP (sequence)) 122 else if (VECTORP (sequence))
107 XSETFASTINT (val, ASIZE (sequence)); 123 val = ASIZE (sequence);
108 else if (CHAR_TABLE_P (sequence)) 124 else if (CHAR_TABLE_P (sequence))
109 XSETFASTINT (val, MAX_CHAR); 125 val = MAX_CHAR;
110 else if (BOOL_VECTOR_P (sequence)) 126 else if (BOOL_VECTOR_P (sequence))
111 XSETFASTINT (val, bool_vector_size (sequence)); 127 val = bool_vector_size (sequence);
112 else if (COMPILEDP (sequence) || RECORDP (sequence)) 128 else if (COMPILEDP (sequence) || RECORDP (sequence))
113 XSETFASTINT (val, PVSIZE (sequence)); 129 val = PVSIZE (sequence);
114 else if (CONSP (sequence)) 130 else if (CONSP (sequence))
115 { 131 val = list_length (sequence);
116 intptr_t i = 0;
117 FOR_EACH_TAIL (sequence)
118 i++;
119 CHECK_LIST_END (sequence, sequence);
120 if (MOST_POSITIVE_FIXNUM < i)
121 overflow_error ();
122 val = make_fixnum (i);
123 }
124 else if (NILP (sequence)) 132 else if (NILP (sequence))
125 XSETFASTINT (val, 0); 133 val = 0;
126 else 134 else
127 wrong_type_argument (Qsequencep, sequence); 135 wrong_type_argument (Qsequencep, sequence);
128 136
129 return val; 137 return make_fixnum (val);
130} 138}
131 139
132DEFUN ("safe-length", Fsafe_length, Ssafe_length, 1, 1, 0, 140DEFUN ("safe-length", Fsafe_length, Ssafe_length, 1, 1, 0,
@@ -1957,24 +1965,15 @@ See also the function `nreverse', which is used more often. */)
1957static Lisp_Object 1965static Lisp_Object
1958sort_list (Lisp_Object list, Lisp_Object predicate) 1966sort_list (Lisp_Object list, Lisp_Object predicate)
1959{ 1967{
1960 Lisp_Object front, back; 1968 ptrdiff_t length = list_length (list);
1961 Lisp_Object len, tem;
1962 EMACS_INT length;
1963
1964 front = list;
1965 len = Flength (list);
1966 length = XFIXNUM (len);
1967 if (length < 2) 1969 if (length < 2)
1968 return list; 1970 return list;
1969 1971
1970 XSETINT (len, (length / 2) - 1); 1972 Lisp_Object tem = Fnthcdr (make_fixnum (length / 2 - 1), list);
1971 tem = Fnthcdr (len, list); 1973 Lisp_Object back = Fcdr (tem);
1972 back = Fcdr (tem);
1973 Fsetcdr (tem, Qnil); 1974 Fsetcdr (tem, Qnil);
1974 1975
1975 front = Fsort (front, predicate); 1976 return merge (Fsort (list, predicate), Fsort (back, predicate), predicate);
1976 back = Fsort (back, predicate);
1977 return merge (front, back, predicate);
1978} 1977}
1979 1978
1980/* Using PRED to compare, return whether A and B are in order. 1979/* Using PRED to compare, return whether A and B are in order.
diff --git a/src/font.c b/src/font.c
index cf68160e59c..3fc77a1d76a 100644
--- a/src/font.c
+++ b/src/font.c
@@ -2174,13 +2174,12 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop)
2174static Lisp_Object 2174static Lisp_Object
2175font_vconcat_entity_vectors (Lisp_Object list) 2175font_vconcat_entity_vectors (Lisp_Object list)
2176{ 2176{
2177 EMACS_INT nargs = XFIXNAT (Flength (list)); 2177 ptrdiff_t nargs = list_length (list);
2178 Lisp_Object *args; 2178 Lisp_Object *args;
2179 USE_SAFE_ALLOCA; 2179 USE_SAFE_ALLOCA;
2180 SAFE_ALLOCA_LISP (args, nargs); 2180 SAFE_ALLOCA_LISP (args, nargs);
2181 ptrdiff_t i;
2182 2181
2183 for (i = 0; i < nargs; i++, list = XCDR (list)) 2182 for (ptrdiff_t i = 0; i < nargs; i++, list = XCDR (list))
2184 args[i] = XCAR (list); 2183 args[i] = XCAR (list);
2185 Lisp_Object result = Fvconcat (nargs, args); 2184 Lisp_Object result = Fvconcat (nargs, args);
2186 SAFE_FREE (); 2185 SAFE_FREE ();
@@ -3241,7 +3240,7 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int
3241 3240
3242 if (! NILP (alters)) 3241 if (! NILP (alters))
3243 { 3242 {
3244 EMACS_INT alterslen = XFIXNAT (Flength (alters)); 3243 EMACS_INT alterslen = list_length (alters);
3245 SAFE_ALLOCA_LISP (family, alterslen + 2); 3244 SAFE_ALLOCA_LISP (family, alterslen + 2);
3246 for (i = 0; CONSP (alters); i++, alters = XCDR (alters)) 3245 for (i = 0; CONSP (alters); i++, alters = XCDR (alters))
3247 family[i] = XCAR (alters); 3246 family[i] = XCAR (alters);
diff --git a/src/frame.c b/src/frame.c
index 6efc2a61095..ca6704a44c0 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -3190,7 +3190,7 @@ list, but are otherwise ignored. */)
3190#endif 3190#endif
3191 3191
3192 { 3192 {
3193 EMACS_INT length = XFIXNAT (Flength (alist)); 3193 EMACS_INT length = list_length (alist);
3194 ptrdiff_t i; 3194 ptrdiff_t i;
3195 Lisp_Object *parms; 3195 Lisp_Object *parms;
3196 Lisp_Object *values; 3196 Lisp_Object *values;
diff --git a/src/fringe.c b/src/fringe.c
index a7e8dad482e..74f41f00873 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -719,7 +719,7 @@ static int
719get_logical_fringe_bitmap (struct window *w, Lisp_Object bitmap, int right_p, int partial_p) 719get_logical_fringe_bitmap (struct window *w, Lisp_Object bitmap, int right_p, int partial_p)
720{ 720{
721 Lisp_Object cmap, bm1 = Qnil, bm2 = Qnil, bm; 721 Lisp_Object cmap, bm1 = Qnil, bm2 = Qnil, bm;
722 EMACS_INT ln1 = 0, ln2 = 0; 722 ptrdiff_t ln1 = 0, ln2 = 0;
723 int ix1 = right_p; 723 int ix1 = right_p;
724 int ix2 = ix1 + (partial_p ? 2 : 0); 724 int ix2 = ix1 + (partial_p ? 2 : 0);
725 725
@@ -743,7 +743,7 @@ get_logical_fringe_bitmap (struct window *w, Lisp_Object bitmap, int right_p, in
743 return NO_FRINGE_BITMAP; 743 return NO_FRINGE_BITMAP;
744 if (CONSP (bm1)) 744 if (CONSP (bm1))
745 { 745 {
746 ln1 = XFIXNUM (Flength (bm1)); 746 ln1 = list_length (bm1);
747 if (partial_p) 747 if (partial_p)
748 { 748 {
749 if (ln1 > ix2) 749 if (ln1 > ix2)
@@ -778,7 +778,7 @@ get_logical_fringe_bitmap (struct window *w, Lisp_Object bitmap, int right_p, in
778 { 778 {
779 if (CONSP (bm2)) 779 if (CONSP (bm2))
780 { 780 {
781 ln2 = XFIXNUM (Flength (bm2)); 781 ln2 = list_length (bm2);
782 if (partial_p) 782 if (partial_p)
783 { 783 {
784 if (ln2 > ix2) 784 if (ln2 > ix2)
diff --git a/src/ftfont.c b/src/ftfont.c
index 6899a5763a8..f5a225be056 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -594,16 +594,14 @@ ftfont_get_open_type_spec (Lisp_Object otf_spec)
594 spec->nfeatures[0] = spec->nfeatures[1] = 0; 594 spec->nfeatures[0] = spec->nfeatures[1] = 0;
595 for (i = 0; i < 2 && ! NILP (otf_spec); i++, otf_spec = XCDR (otf_spec)) 595 for (i = 0; i < 2 && ! NILP (otf_spec); i++, otf_spec = XCDR (otf_spec))
596 { 596 {
597 Lisp_Object len;
598
599 val = XCAR (otf_spec); 597 val = XCAR (otf_spec);
600 if (NILP (val)) 598 if (NILP (val))
601 continue; 599 continue;
602 len = Flength (val); 600 ptrdiff_t len = list_length (val);
603 spec->features[i] = 601 spec->features[i] =
604 (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < XFIXNUM (len) 602 (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < len
605 ? 0 603 ? 0
606 : malloc (XFIXNUM (len) * sizeof *spec->features[i])); 604 : malloc (len * sizeof *spec->features[i]));
607 if (! spec->features[i]) 605 if (! spec->features[i])
608 { 606 {
609 if (i > 0 && spec->features[0]) 607 if (i > 0 && spec->features[0])
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 2eac28798bc..92199bb0af2 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -4299,7 +4299,7 @@ xg_print_frames_dialog (Lisp_Object frames)
4299 gtk_print_operation_set_print_settings (print, print_settings); 4299 gtk_print_operation_set_print_settings (print, print_settings);
4300 if (page_setup != NULL) 4300 if (page_setup != NULL)
4301 gtk_print_operation_set_default_page_setup (print, page_setup); 4301 gtk_print_operation_set_default_page_setup (print, page_setup);
4302 gtk_print_operation_set_n_pages (print, XFIXNUM (Flength (frames))); 4302 gtk_print_operation_set_n_pages (print, list_length (frames));
4303 g_signal_connect (print, "draw-page", G_CALLBACK (draw_page), &frames); 4303 g_signal_connect (print, "draw-page", G_CALLBACK (draw_page), &frames);
4304 res = gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, 4304 res = gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
4305 NULL, NULL); 4305 NULL, NULL);
diff --git a/src/keymap.c b/src/keymap.c
index 21d37328ade..dda552ba471 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -2042,7 +2042,7 @@ For an approximate inverse of this, see `kbd'. */)
2042 else if (VECTORP (list)) 2042 else if (VECTORP (list))
2043 size = ASIZE (list); 2043 size = ASIZE (list);
2044 else if (CONSP (list)) 2044 else if (CONSP (list))
2045 size = XFIXNUM (Flength (list)); 2045 size = list_length (list);
2046 else 2046 else
2047 wrong_type_argument (Qarrayp, list); 2047 wrong_type_argument (Qarrayp, list);
2048 2048
diff --git a/src/kqueue.c b/src/kqueue.c
index 655bfd58d3b..43e75cac310 100644
--- a/src/kqueue.c
+++ b/src/kqueue.c
@@ -395,11 +395,12 @@ only when the upper directory of the renamed file is watched. */)
395 maxfd = 256; 395 maxfd = 256;
396 396
397 /* We assume 50 file descriptors are sufficient for the rest of Emacs. */ 397 /* We assume 50 file descriptors are sufficient for the rest of Emacs. */
398 if ((maxfd - 50) < XFIXNUM (Flength (watch_list))) 398 ptrdiff_t watch_list_len = list_length (watch_list);
399 if (maxfd - 50 < watch_list_len)
399 xsignal2 400 xsignal2
400 (Qfile_notify_error, 401 (Qfile_notify_error,
401 build_string ("File watching not possible, no file descriptor left"), 402 build_string ("File watching not possible, no file descriptor left"),
402 Flength (watch_list)); 403 make_fixnum (watch_list_len));
403 404
404 if (kqueuefd < 0) 405 if (kqueuefd < 0)
405 { 406 {
diff --git a/src/lisp.h b/src/lisp.h
index dce61c165cf..faf5a4ad407 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3413,6 +3413,7 @@ extern void syms_of_syntax (void);
3413 3413
3414/* Defined in fns.c. */ 3414/* Defined in fns.c. */
3415enum { NEXT_ALMOST_PRIME_LIMIT = 11 }; 3415enum { NEXT_ALMOST_PRIME_LIMIT = 11 };
3416extern ptrdiff_t list_length (Lisp_Object);
3416extern EMACS_INT next_almost_prime (EMACS_INT) ATTRIBUTE_CONST; 3417extern EMACS_INT next_almost_prime (EMACS_INT) ATTRIBUTE_CONST;
3417extern Lisp_Object larger_vector (Lisp_Object, ptrdiff_t, ptrdiff_t); 3418extern Lisp_Object larger_vector (Lisp_Object, ptrdiff_t, ptrdiff_t);
3418extern void sweep_weak_hash_tables (void); 3419extern void sweep_weak_hash_tables (void);
diff --git a/src/lread.c b/src/lread.c
index 02f7caadeda..5a595f2119b 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -2879,7 +2879,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2879 /* Sub char-table can't be read as a regular 2879 /* Sub char-table can't be read as a regular
2880 vector because of a two C integer fields. */ 2880 vector because of a two C integer fields. */
2881 Lisp_Object tbl, tmp = read_list (1, readcharfun); 2881 Lisp_Object tbl, tmp = read_list (1, readcharfun);
2882 ptrdiff_t size = XFIXNUM (Flength (tmp)); 2882 ptrdiff_t size = list_length (tmp);
2883 int i, depth, min_char; 2883 int i, depth, min_char;
2884 struct Lisp_Cons *cell; 2884 struct Lisp_Cons *cell;
2885 2885
@@ -3846,8 +3846,7 @@ static Lisp_Object
3846read_vector (Lisp_Object readcharfun, bool bytecodeflag) 3846read_vector (Lisp_Object readcharfun, bool bytecodeflag)
3847{ 3847{
3848 Lisp_Object tem = read_list (1, readcharfun); 3848 Lisp_Object tem = read_list (1, readcharfun);
3849 Lisp_Object len = Flength (tem); 3849 ptrdiff_t size = list_length (tem);
3850 ptrdiff_t size = XFIXNAT (len);
3851 if (bytecodeflag && size <= COMPILED_STACK_DEPTH) 3850 if (bytecodeflag && size <= COMPILED_STACK_DEPTH)
3852 error ("Invalid byte code"); 3851 error ("Invalid byte code");
3853 Lisp_Object vector = make_nil_vector (size); 3852 Lisp_Object vector = make_nil_vector (size);
diff --git a/src/macfont.m b/src/macfont.m
index 0e90eb44eeb..09c4ff31c88 100644
--- a/src/macfont.m
+++ b/src/macfont.m
@@ -1791,16 +1791,14 @@ macfont_get_open_type_spec (Lisp_Object otf_spec)
1791 spec->nfeatures[0] = spec->nfeatures[1] = 0; 1791 spec->nfeatures[0] = spec->nfeatures[1] = 0;
1792 for (i = 0; i < 2 && ! NILP (otf_spec); i++, otf_spec = XCDR (otf_spec)) 1792 for (i = 0; i < 2 && ! NILP (otf_spec); i++, otf_spec = XCDR (otf_spec))
1793 { 1793 {
1794 Lisp_Object len;
1795
1796 val = XCAR (otf_spec); 1794 val = XCAR (otf_spec);
1797 if (NILP (val)) 1795 if (NILP (val))
1798 continue; 1796 continue;
1799 len = Flength (val); 1797 ptrdiff_t len = list_length (val);
1800 spec->features[i] = 1798 spec->features[i] =
1801 (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < XFIXNUM (len) 1799 (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < len
1802 ? 0 1800 ? 0
1803 : malloc (XFIXNUM (len) * sizeof *spec->features[i])); 1801 : malloc (len * sizeof *spec->features[i]));
1804 if (! spec->features[i]) 1802 if (! spec->features[i])
1805 { 1803 {
1806 if (i > 0 && spec->features[0]) 1804 if (i > 0 && spec->features[0])
diff --git a/src/menu.c b/src/menu.c
index c35d711b314..c0e5bd9caf6 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -524,19 +524,15 @@ bool
524parse_single_submenu (Lisp_Object item_key, Lisp_Object item_name, 524parse_single_submenu (Lisp_Object item_key, Lisp_Object item_name,
525 Lisp_Object maps) 525 Lisp_Object maps)
526{ 526{
527 Lisp_Object length;
528 EMACS_INT len;
529 Lisp_Object *mapvec; 527 Lisp_Object *mapvec;
530 ptrdiff_t i;
531 bool top_level_items = 0; 528 bool top_level_items = 0;
532 USE_SAFE_ALLOCA; 529 USE_SAFE_ALLOCA;
533 530
534 length = Flength (maps); 531 ptrdiff_t len = list_length (maps);
535 len = XFIXNUM (length);
536 532
537 /* Convert the list MAPS into a vector MAPVEC. */ 533 /* Convert the list MAPS into a vector MAPVEC. */
538 SAFE_ALLOCA_LISP (mapvec, len); 534 SAFE_ALLOCA_LISP (mapvec, len);
539 for (i = 0; i < len; i++) 535 for (ptrdiff_t i = 0; i < len; i++)
540 { 536 {
541 mapvec[i] = Fcar (maps); 537 mapvec[i] = Fcar (maps);
542 maps = Fcdr (maps); 538 maps = Fcdr (maps);
@@ -544,7 +540,7 @@ parse_single_submenu (Lisp_Object item_key, Lisp_Object item_name,
544 540
545 /* Loop over the given keymaps, making a pane for each map. 541 /* Loop over the given keymaps, making a pane for each map.
546 But don't make a pane that is empty--ignore that map instead. */ 542 But don't make a pane that is empty--ignore that map instead. */
547 for (i = 0; i < len; i++) 543 for (ptrdiff_t i = 0; i < len; i++)
548 { 544 {
549 if (!KEYMAPP (mapvec[i])) 545 if (!KEYMAPP (mapvec[i]))
550 { 546 {
@@ -1309,7 +1305,7 @@ x_popup_menu_1 (Lisp_Object position, Lisp_Object menu)
1309 else if (CONSP (menu) && KEYMAPP (XCAR (menu))) 1305 else if (CONSP (menu) && KEYMAPP (XCAR (menu)))
1310 { 1306 {
1311 /* We were given a list of keymaps. */ 1307 /* We were given a list of keymaps. */
1312 EMACS_INT nmaps = XFIXNAT (Flength (menu)); 1308 ptrdiff_t nmaps = list_length (menu);
1313 Lisp_Object *maps; 1309 Lisp_Object *maps;
1314 ptrdiff_t i; 1310 ptrdiff_t i;
1315 USE_SAFE_ALLOCA; 1311 USE_SAFE_ALLOCA;
diff --git a/src/minibuf.c b/src/minibuf.c
index 8017da194b0..c1fbfb40857 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -780,8 +780,7 @@ read_minibuf_unwind (void)
780 780
781 /* Restore prompt, etc, from outer minibuffer level. */ 781 /* Restore prompt, etc, from outer minibuffer level. */
782 Lisp_Object key_vec = Fcar (minibuf_save_list); 782 Lisp_Object key_vec = Fcar (minibuf_save_list);
783 eassert (VECTORP (key_vec)); 783 this_command_key_count = ASIZE (key_vec);
784 this_command_key_count = XFIXNAT (Flength (key_vec));
785 this_command_keys = key_vec; 784 this_command_keys = key_vec;
786 minibuf_save_list = Fcdr (minibuf_save_list); 785 minibuf_save_list = Fcdr (minibuf_save_list);
787 minibuf_prompt = Fcar (minibuf_save_list); 786 minibuf_prompt = Fcar (minibuf_save_list);
@@ -1783,7 +1782,7 @@ If FLAG is nil, invoke `try-completion'; if it is t, invoke
1783 while (CONSP (bufs) && SREF (XCAR (bufs), 0) == ' ') 1782 while (CONSP (bufs) && SREF (XCAR (bufs), 0) == ' ')
1784 bufs = XCDR (bufs); 1783 bufs = XCDR (bufs);
1785 if (NILP (bufs)) 1784 if (NILP (bufs))
1786 return (EQ (Flength (res), Flength (Vbuffer_alist)) 1785 return (list_length (res) == list_length (Vbuffer_alist)
1787 /* If all bufs are internal don't strip them out. */ 1786 /* If all bufs are internal don't strip them out. */
1788 ? res : bufs); 1787 ? res : bufs);
1789 res = bufs; 1788 res = bufs;
diff --git a/src/nsfont.m b/src/nsfont.m
index d4639dcca8c..b59f87f4682 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -576,7 +576,7 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch)
576 576
577 /* Add synthItal member if needed. */ 577 /* Add synthItal member if needed. */
578 family = [fdesc objectForKey: NSFontFamilyAttribute]; 578 family = [fdesc objectForKey: NSFontFamilyAttribute];
579 if (family != nil && !foundItal && XFIXNUM (Flength (list)) > 0) 579 if (family != nil && !foundItal && !NILP (list))
580 { 580 {
581 NSFontDescriptor *s1 = [NSFontDescriptor new]; 581 NSFontDescriptor *s1 = [NSFontDescriptor new];
582 NSFontDescriptor *sDesc 582 NSFontDescriptor *sDesc
@@ -595,8 +595,8 @@ ns_findfonts (Lisp_Object font_spec, BOOL isMatch)
595 return ns_fallback_entity (); 595 return ns_fallback_entity ();
596 596
597 if (NSFONT_TRACE) 597 if (NSFONT_TRACE)
598 fprintf (stderr, " Returning %"pI"d entities.\n", 598 fprintf (stderr, " Returning %"pD"d entities.\n",
599 XFIXNUM (Flength (list))); 599 list_length (list));
600 600
601 return list; 601 return list;
602} 602}
@@ -667,8 +667,8 @@ nsfont_list_family (struct frame *f)
667 /* FIXME: escape the name? */ 667 /* FIXME: escape the name? */
668 668
669 if (NSFONT_TRACE) 669 if (NSFONT_TRACE)
670 fprintf (stderr, "nsfont: list families returning %"pI"d entries\n", 670 fprintf (stderr, "nsfont: list families returning %"pD"d entries\n",
671 XFIXNUM (Flength (list))); 671 list_length (list));
672 672
673 unblock_input (); 673 unblock_input ();
674 return list; 674 return list;
diff --git a/src/process.c b/src/process.c
index b2a7f38317a..edf633e512e 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1804,7 +1804,7 @@ usage: (make-process &rest ARGS) */)
1804 val = Vcoding_system_for_read; 1804 val = Vcoding_system_for_read;
1805 if (NILP (val)) 1805 if (NILP (val))
1806 { 1806 {
1807 ptrdiff_t nargs2 = 3 + XFIXNUM (Flength (command)); 1807 ptrdiff_t nargs2 = 3 + list_length (command);
1808 Lisp_Object tem2; 1808 Lisp_Object tem2;
1809 SAFE_ALLOCA_LISP (args2, nargs2); 1809 SAFE_ALLOCA_LISP (args2, nargs2);
1810 ptrdiff_t i = 0; 1810 ptrdiff_t i = 0;
@@ -1834,7 +1834,7 @@ usage: (make-process &rest ARGS) */)
1834 { 1834 {
1835 if (EQ (coding_systems, Qt)) 1835 if (EQ (coding_systems, Qt))
1836 { 1836 {
1837 ptrdiff_t nargs2 = 3 + XFIXNUM (Flength (command)); 1837 ptrdiff_t nargs2 = 3 + list_length (command);
1838 Lisp_Object tem2; 1838 Lisp_Object tem2;
1839 SAFE_ALLOCA_LISP (args2, nargs2); 1839 SAFE_ALLOCA_LISP (args2, nargs2);
1840 ptrdiff_t i = 0; 1840 ptrdiff_t i = 0;
diff --git a/src/search.c b/src/search.c
index 702e6e3d8e7..f97dbe73341 100644
--- a/src/search.c
+++ b/src/search.c
@@ -2992,13 +2992,11 @@ If optional arg RESEAT is non-nil, make markers on LIST point nowhere. */)
2992 2992
2993 /* Allocate registers if they don't already exist. */ 2993 /* Allocate registers if they don't already exist. */
2994 { 2994 {
2995 EMACS_INT length = XFIXNAT (Flength (list)) / 2; 2995 ptrdiff_t length = list_length (list) / 2;
2996 2996
2997 if (length > search_regs.num_regs) 2997 if (length > search_regs.num_regs)
2998 { 2998 {
2999 ptrdiff_t num_regs = search_regs.num_regs; 2999 ptrdiff_t num_regs = search_regs.num_regs;
3000 if (PTRDIFF_MAX < length)
3001 memory_full (SIZE_MAX);
3002 search_regs.start = 3000 search_regs.start =
3003 xpalloc (search_regs.start, &num_regs, length - num_regs, 3001 xpalloc (search_regs.start, &num_regs, length - num_regs,
3004 min (PTRDIFF_MAX, UINT_MAX), sizeof *search_regs.start); 3002 min (PTRDIFF_MAX, UINT_MAX), sizeof *search_regs.start);
diff --git a/src/xdisp.c b/src/xdisp.c
index 8b091c81bef..7725570ced3 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -24137,7 +24137,7 @@ store_mode_line_string (const char *string, Lisp_Object lisp_string,
24137 } 24137 }
24138 else 24138 else
24139 { 24139 {
24140 len = XFIXNAT (Flength (lisp_string)); 24140 len = SCHARS (lisp_string);
24141 if (precision > 0 && len > precision) 24141 if (precision > 0 && len > precision)
24142 { 24142 {
24143 len = precision; 24143 len = precision;
diff --git a/src/xfaces.c b/src/xfaces.c
index 8fe99e7655d..cffa89e1f39 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -1424,7 +1424,6 @@ the face font sort order. */)
1424 Lisp_Object font_spec, list, *drivers, vec; 1424 Lisp_Object font_spec, list, *drivers, vec;
1425 struct frame *f = decode_live_frame (frame); 1425 struct frame *f = decode_live_frame (frame);
1426 ptrdiff_t i, nfonts; 1426 ptrdiff_t i, nfonts;
1427 EMACS_INT ndrivers;
1428 Lisp_Object result; 1427 Lisp_Object result;
1429 USE_SAFE_ALLOCA; 1428 USE_SAFE_ALLOCA;
1430 1429
@@ -1457,7 +1456,7 @@ the face font sort order. */)
1457 font_props_for_sorting[i++] = FONT_ADSTYLE_INDEX; 1456 font_props_for_sorting[i++] = FONT_ADSTYLE_INDEX;
1458 font_props_for_sorting[i++] = FONT_REGISTRY_INDEX; 1457 font_props_for_sorting[i++] = FONT_REGISTRY_INDEX;
1459 1458
1460 ndrivers = XFIXNUM (Flength (list)); 1459 ptrdiff_t ndrivers = list_length (list);
1461 SAFE_ALLOCA_LISP (drivers, ndrivers); 1460 SAFE_ALLOCA_LISP (drivers, ndrivers);
1462 for (i = 0; i < ndrivers; i++, list = XCDR (list)) 1461 for (i = 0; i < ndrivers; i++, list = XCDR (list))
1463 drivers[i] = XCAR (list); 1462 drivers[i] = XCAR (list);