emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master a20f2b0ff9: Speed up calls to C primitives


From: Mattias Engdegård
Subject: master a20f2b0ff9: Speed up calls to C primitives
Date: Tue, 1 Feb 2022 11:39:37 -0500 (EST)

branch: master
commit a20f2b0ff9f8adcc4ca2f2be56109a7d72d11847
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>

    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.
---
 src/eval.c | 85 ++++++++++++++++++++++++--------------------------------------
 1 file changed, 33 insertions(+), 52 deletions(-)

diff --git a/src/eval.c b/src/eval.c
index 4e8a4e9d9d..4f1c907751 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3104,80 +3104,61 @@ usage: (funcall FUNCTION &rest ARGUMENTS)  */)
 Lisp_Object
 funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args)
 {
-  if (numargs < subr->min_args
-      || (subr->max_args >= 0 && subr->max_args < numargs))
+  eassume (numargs >= 0);
+  /* Conforming call to finite-arity subr.  */
+  if (numargs >= subr->min_args && numargs <= subr->max_args)
     {
-      Lisp_Object fun;
-      XSETSUBR (fun, subr);
-      xsignal2 (Qwrong_number_of_arguments, fun, make_fixnum (numargs));
-    }
-
-  else if (subr->max_args == UNEVALLED)
-    {
-      Lisp_Object fun;
-      XSETSUBR (fun, subr);
-      xsignal1 (Qinvalid_function, fun);
-    }
-
-  else if (subr->max_args == MANY)
-    return (subr->function.aMANY) (numargs, args);
-  else
-    {
-      Lisp_Object internal_argbuf[8];
-      Lisp_Object *internal_args;
-      if (subr->max_args > numargs)
+      Lisp_Object argbuf[8];
+      Lisp_Object *a;
+      if (numargs < subr->max_args)
         {
-          eassert (subr->max_args <= ARRAYELTS (internal_argbuf));
-          internal_args = internal_argbuf;
-          memcpy (internal_args, args, numargs * word_size);
-          memclear (internal_args + numargs,
-                    (subr->max_args - numargs) * word_size);
+          eassume (subr->max_args <= ARRAYELTS (argbuf));
+          a = argbuf;
+          memcpy (a, args, numargs * word_size);
+          memclear (a + numargs, (subr->max_args - numargs) * word_size);
         }
       else
-        internal_args = args;
+        a = args;
       switch (subr->max_args)
         {
         case 0:
-          return (subr->function.a0 ());
+          return subr->function.a0 ();
         case 1:
-          return (subr->function.a1 (internal_args[0]));
+          return subr->function.a1 (a[0]);
         case 2:
-          return (subr->function.a2
-                  (internal_args[0], internal_args[1]));
+          return subr->function.a2 (a[0], a[1]);
         case 3:
-          return (subr->function.a3
-                  (internal_args[0], internal_args[1], internal_args[2]));
+          return subr->function.a3 (a[0], a[1], a[2]);
         case 4:
-          return (subr->function.a4
-                  (internal_args[0], internal_args[1], internal_args[2],
-                   internal_args[3]));
+          return subr->function.a4 (a[0], a[1], a[2], a[3]);
         case 5:
-          return (subr->function.a5
-                  (internal_args[0], internal_args[1], internal_args[2],
-                   internal_args[3], internal_args[4]));
+          return subr->function.a5 (a[0], a[1], a[2], a[3], a[4]);
         case 6:
-          return (subr->function.a6
-                  (internal_args[0], internal_args[1], internal_args[2],
-                   internal_args[3], internal_args[4], internal_args[5]));
+          return subr->function.a6 (a[0], a[1], a[2], a[3], a[4], a[5]);
         case 7:
-          return (subr->function.a7
-                  (internal_args[0], internal_args[1], internal_args[2],
-                   internal_args[3], internal_args[4], internal_args[5],
-                   internal_args[6]));
+          return subr->function.a7 (a[0], a[1], a[2], a[3], a[4], a[5], a[6]);
         case 8:
-          return (subr->function.a8
-                  (internal_args[0], internal_args[1], internal_args[2],
-                   internal_args[3], internal_args[4], internal_args[5],
-                   internal_args[6], internal_args[7]));
-
+          return subr->function.a8 (a[0], a[1], a[2], a[3], a[4], a[5], a[6],
+                                   a[7]);
         default:
-
           /* If a subr takes more than 8 arguments without using MANY
              or UNEVALLED, we need to extend this function to support it.
              Until this is done, there is no way to call the function.  */
           emacs_abort ();
         }
     }
+
+  /* Call to n-adic subr.  */
+  if (subr->max_args == MANY)
+    return subr->function.aMANY (numargs, args);
+
+  /* Anything else is an error.  */
+  Lisp_Object fun;
+  XSETSUBR (fun, subr);
+  if (subr->max_args >= 0)
+    xsignal2 (Qwrong_number_of_arguments, fun, make_fixnum (numargs));
+  else
+    xsignal1 (Qinvalid_function, fun);
 }
 
 /* Call the compiled Lisp function FUN.  If we have not yet read FUN's



reply via email to

[Prev in Thread] Current Thread [Next in Thread]