diff options
| author | Mattias EngdegÄrd | 2022-02-01 16:18:47 +0100 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2022-02-01 17:37:05 +0100 |
| commit | a20f2b0ff9f8adcc4ca2f2be56109a7d72d11847 (patch) | |
| tree | fca1c8d5e124ecd01bb22c94e6cd191c343e36e3 /src/eval.c | |
| parent | 2b9c648de644d19df3ae51cc495816885ac72fe4 (diff) | |
| download | emacs-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.c | 85 |
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) */) | |||
| 3104 | Lisp_Object | 3104 | Lisp_Object |
| 3105 | funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args) | 3105 | funcall_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 |