aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorMattias EngdegÄrd2022-02-01 16:18:47 +0100
committerMattias EngdegÄrd2022-02-01 17:37:05 +0100
commita20f2b0ff9f8adcc4ca2f2be56109a7d72d11847 (patch)
treefca1c8d5e124ecd01bb22c94e6cd191c343e36e3 /src/eval.c
parent2b9c648de644d19df3ae51cc495816885ac72fe4 (diff)
downloademacs-a20f2b0ff9f8adcc4ca2f2be56109a7d72d11847.tar.gz
emacs-a20f2b0ff9f8adcc4ca2f2be56109a7d72d11847.zip
Speed up calls to C primitives
* src/eval.c (funcall_subr): Test most likely cases first (conforming calls to finite-arity or n-adic SUBRs), and the error cases last, instead of doing it the other way around. Simplify.
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c85
1 files changed, 33 insertions, 52 deletions
diff --git a/src/eval.c b/src/eval.c
index 4e8a4e9d9da..4f1c9077511 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3104,80 +3104,61 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
3104Lisp_Object 3104Lisp_Object
3105funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args) 3105funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args)
3106{ 3106{
3107 if (numargs < subr->min_args 3107 eassume (numargs >= 0);
3108 || (subr->max_args >= 0 && subr->max_args < numargs)) 3108 /* Conforming call to finite-arity subr. */
3109 if (numargs >= subr->min_args && numargs <= subr->max_args)
3109 { 3110 {
3110 Lisp_Object fun; 3111 Lisp_Object argbuf[8];
3111 XSETSUBR (fun, subr); 3112 Lisp_Object *a;
3112 xsignal2 (Qwrong_number_of_arguments, fun, make_fixnum (numargs)); 3113 if (numargs < subr->max_args)
3113 }
3114
3115 else if (subr->max_args == UNEVALLED)
3116 {
3117 Lisp_Object fun;
3118 XSETSUBR (fun, subr);
3119 xsignal1 (Qinvalid_function, fun);
3120 }
3121
3122 else if (subr->max_args == MANY)
3123 return (subr->function.aMANY) (numargs, args);
3124 else
3125 {
3126 Lisp_Object internal_argbuf[8];
3127 Lisp_Object *internal_args;
3128 if (subr->max_args > numargs)
3129 { 3114 {
3130 eassert (subr->max_args <= ARRAYELTS (internal_argbuf)); 3115 eassume (subr->max_args <= ARRAYELTS (argbuf));
3131 internal_args = internal_argbuf; 3116 a = argbuf;
3132 memcpy (internal_args, args, numargs * word_size); 3117 memcpy (a, args, numargs * word_size);
3133 memclear (internal_args + numargs, 3118 memclear (a + numargs, (subr->max_args - numargs) * word_size);
3134 (subr->max_args - numargs) * word_size);
3135 } 3119 }
3136 else 3120 else
3137 internal_args = args; 3121 a = args;
3138 switch (subr->max_args) 3122 switch (subr->max_args)
3139 { 3123 {
3140 case 0: 3124 case 0:
3141 return (subr->function.a0 ()); 3125 return subr->function.a0 ();
3142 case 1: 3126 case 1:
3143 return (subr->function.a1 (internal_args[0])); 3127 return subr->function.a1 (a[0]);
3144 case 2: 3128 case 2:
3145 return (subr->function.a2 3129 return subr->function.a2 (a[0], a[1]);
3146 (internal_args[0], internal_args[1]));
3147 case 3: 3130 case 3:
3148 return (subr->function.a3 3131 return subr->function.a3 (a[0], a[1], a[2]);
3149 (internal_args[0], internal_args[1], internal_args[2]));
3150 case 4: 3132 case 4:
3151 return (subr->function.a4 3133 return subr->function.a4 (a[0], a[1], a[2], a[3]);
3152 (internal_args[0], internal_args[1], internal_args[2],
3153 internal_args[3]));
3154 case 5: 3134 case 5:
3155 return (subr->function.a5 3135 return subr->function.a5 (a[0], a[1], a[2], a[3], a[4]);
3156 (internal_args[0], internal_args[1], internal_args[2],
3157 internal_args[3], internal_args[4]));
3158 case 6: 3136 case 6:
3159 return (subr->function.a6 3137 return subr->function.a6 (a[0], a[1], a[2], a[3], a[4], a[5]);
3160 (internal_args[0], internal_args[1], internal_args[2],
3161 internal_args[3], internal_args[4], internal_args[5]));
3162 case 7: 3138 case 7:
3163 return (subr->function.a7 3139 return subr->function.a7 (a[0], a[1], a[2], a[3], a[4], a[5], a[6]);
3164 (internal_args[0], internal_args[1], internal_args[2],
3165 internal_args[3], internal_args[4], internal_args[5],
3166 internal_args[6]));
3167 case 8: 3140 case 8:
3168 return (subr->function.a8 3141 return subr->function.a8 (a[0], a[1], a[2], a[3], a[4], a[5], a[6],
3169 (internal_args[0], internal_args[1], internal_args[2], 3142 a[7]);
3170 internal_args[3], internal_args[4], internal_args[5],
3171 internal_args[6], internal_args[7]));
3172
3173 default: 3143 default:
3174
3175 /* If a subr takes more than 8 arguments without using MANY 3144 /* If a subr takes more than 8 arguments without using MANY
3176 or UNEVALLED, we need to extend this function to support it. 3145 or UNEVALLED, we need to extend this function to support it.
3177 Until this is done, there is no way to call the function. */ 3146 Until this is done, there is no way to call the function. */
3178 emacs_abort (); 3147 emacs_abort ();
3179 } 3148 }
3180 } 3149 }
3150
3151 /* Call to n-adic subr. */
3152 if (subr->max_args == MANY)
3153 return subr->function.aMANY (numargs, args);
3154
3155 /* Anything else is an error. */
3156 Lisp_Object fun;
3157 XSETSUBR (fun, subr);
3158 if (subr->max_args >= 0)
3159 xsignal2 (Qwrong_number_of_arguments, fun, make_fixnum (numargs));
3160 else
3161 xsignal1 (Qinvalid_function, fun);
3181} 3162}
3182 3163
3183/* Call the compiled Lisp function FUN. If we have not yet read FUN's 3164/* Call the compiled Lisp function FUN. If we have not yet read FUN's