emacs-diffs
[Top][All Lists]
Advanced

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

scratch/bytecode-speedup 09b5ed93b1 07/11: Remove nil check in exec_byte


From: Mattias Engdegård
Subject: scratch/bytecode-speedup 09b5ed93b1 07/11: Remove nil check in exec_byte_code
Date: Tue, 11 Jan 2022 11:50:48 -0500 (EST)

branch: scratch/bytecode-speedup
commit 09b5ed93b193c4480c3c5aa7483b70348821e23b
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>

    Remove nil check in exec_byte_code
    
    Since we pass no arguments to a non-lexbind bytecode function, we can
    specify its arity as 0 instead of nil and save a test and branch.
    
    * src/bytecode.c (Fbyte_code, exec_byte_code):
    * src/eval.c (fetch_and_exec_byte_code, funcall_lambda):
    * src/lisp.h:
    Change the args_template parameter type to ptrdiff_t, since it is now
    always a small integer, in exec_byte_code and
    fetch_and_exec_byte_code, all callers adjusted.
---
 src/bytecode.c | 54 ++++++++++++++++++++++++++----------------------------
 src/eval.c     | 10 ++++++----
 src/lisp.h     |  2 +-
 3 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/src/bytecode.c b/src/bytecode.c
index 9e31da79a0..ae6eec09d4 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -333,7 +333,7 @@ If the third argument is incorrect, Emacs may crash.  */)
     }
   pin_string (bytestr);  // Bytecode must be immovable.
 
-  return exec_byte_code (bytestr, vector, maxdepth, Qnil, 0, NULL);
+  return exec_byte_code (bytestr, vector, maxdepth, 0, 0, NULL);
 }
 
 static void
@@ -344,15 +344,14 @@ bcall0 (Lisp_Object f)
 
 /* Execute the byte-code in BYTESTR.  VECTOR is the constant vector, and
    MAXDEPTH is the maximum stack depth used (if MAXDEPTH is incorrect,
-   emacs may crash!).  If ARGS_TEMPLATE is non-nil, it should be a lisp
-   argument list (including &rest, &optional, etc.), and ARGS, of size
-   NARGS, should be a vector of the actual arguments.  The arguments in
-   ARGS are pushed on the stack according to ARGS_TEMPLATE before
-   executing BYTESTR.  */
+   emacs may crash!).  ARGS_TEMPLATE is the function arity encoded as an
+   integer, and ARGS, of size NARGS, should be a vector of the actual
+   arguments.  The arguments in ARGS are pushed on the stack according
+   to ARGS_TEMPLATE before executing BYTESTR.  */
 
 Lisp_Object
 exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
-               Lisp_Object args_template, ptrdiff_t nargs, Lisp_Object *args)
+               ptrdiff_t args_template, ptrdiff_t nargs, Lisp_Object *args)
 {
 #ifdef BYTE_CODE_METER
   int volatile this_op = 0;
@@ -384,26 +383,25 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, 
Lisp_Object maxdepth,
   unsigned char const *pc = bytestr_data;
   ptrdiff_t count = SPECPDL_INDEX ();
 
-  if (!NILP (args_template))
-    {
-      eassert (FIXNUMP (args_template));
-      ptrdiff_t at = XFIXNUM (args_template);
-      bool rest = (at & 128) != 0;
-      int mandatory = at & 127;
-      ptrdiff_t nonrest = at >> 8;
-      if (! (mandatory <= nargs && (rest || nargs <= nonrest)))
-       Fsignal (Qwrong_number_of_arguments,
-                list2 (Fcons (make_fixnum (mandatory), make_fixnum (nonrest)),
-                       make_fixnum (nargs)));
-      ptrdiff_t pushedargs = min (nonrest, nargs);
-      for (ptrdiff_t i = 0; i < pushedargs; i++, args++)
-       PUSH (*args);
-      if (nonrest < nargs)
-       PUSH (Flist (nargs - nonrest, args));
-      else
-       for (ptrdiff_t i = nargs - rest; i < nonrest; i++)
-         PUSH (Qnil);
-    }
+  /* ARGS_TEMPLATE is composed of bit fields:
+     bits 0..6    minimum number of arguments
+     bits 7       1 iff &rest argument present
+     bits 8..14   maximum number of arguments */
+  bool rest = (args_template & 128) != 0;
+  int mandatory = args_template & 127;
+  ptrdiff_t nonrest = args_template >> 8;
+  if (! (mandatory <= nargs && (rest || nargs <= nonrest)))
+    Fsignal (Qwrong_number_of_arguments,
+            list2 (Fcons (make_fixnum (mandatory), make_fixnum (nonrest)),
+                   make_fixnum (nargs)));
+  ptrdiff_t pushedargs = min (nonrest, nargs);
+  for (ptrdiff_t i = 0; i < pushedargs; i++, args++)
+    PUSH (*args);
+  if (nonrest < nargs)
+    PUSH (Flist (nargs - nonrest, args));
+  else
+    for (ptrdiff_t i = nargs - rest; i < nonrest; i++)
+      PUSH (Qnil);
 
   while (true)
     {
@@ -671,7 +669,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, 
Lisp_Object maxdepth,
              val = exec_byte_code (bytecode,
                                    AREF (fun, COMPILED_CONSTANTS),
                                    AREF (fun, COMPILED_STACK_DEPTH),
-                                   template, numargs, args);
+                                   XFIXNUM (template), numargs, args);
            else if (SUBRP (fun) && !SUBR_NATIVE_COMPILED_DYNP (fun))
              val = funcall_subr (XSUBR (fun), numargs, args);
            else
diff --git a/src/eval.c b/src/eval.c
index 14f883cde2..8fa1f7cba9 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3223,15 +3223,16 @@ funcall_subr (struct Lisp_Subr *subr, ptrdiff_t 
numargs, Lisp_Object *args)
    bytecode string and constants vector, fetch them from the file first.  */
 
 static Lisp_Object
-fetch_and_exec_byte_code (Lisp_Object fun, Lisp_Object syms_left,
+fetch_and_exec_byte_code (Lisp_Object fun, ptrdiff_t args_template,
                          ptrdiff_t nargs, Lisp_Object *args)
 {
   if (CONSP (AREF (fun, COMPILED_BYTECODE)))
     Ffetch_bytecode (fun);
+
   return exec_byte_code (AREF (fun, COMPILED_BYTECODE),
                         AREF (fun, COMPILED_CONSTANTS),
                         AREF (fun, COMPILED_STACK_DEPTH),
-                        syms_left, nargs, args);
+                        args_template, nargs, args);
 }
 
 static Lisp_Object
@@ -3309,7 +3310,8 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
           argument-binding code below instead (as do all interpreted
           functions, even lexically bound ones).  */
        {
-         return fetch_and_exec_byte_code (fun, syms_left, nargs, arg_vector);
+         return fetch_and_exec_byte_code (fun, XFIXNUM (syms_left),
+                                          nargs, arg_vector);
        }
       lexenv = Qnil;
     }
@@ -3395,7 +3397,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
       val = XSUBR (fun)->function.a0 ();
     }
   else
-    val = fetch_and_exec_byte_code (fun, Qnil, 0, NULL);
+    val = fetch_and_exec_byte_code (fun, 0, 0, NULL);
 
   return unbind_to (count, val);
 }
diff --git a/src/lisp.h b/src/lisp.h
index 140c7cd066..1187ad3d52 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4640,7 +4640,7 @@ extern int read_bytecode_char (bool);
 /* Defined in bytecode.c.  */
 extern void syms_of_bytecode (void);
 extern Lisp_Object exec_byte_code (Lisp_Object, Lisp_Object, Lisp_Object,
-                                  Lisp_Object, ptrdiff_t, Lisp_Object *);
+                                  ptrdiff_t, ptrdiff_t, Lisp_Object *);
 extern Lisp_Object get_byte_code_arity (Lisp_Object);
 
 /* Defined in macros.c.  */



reply via email to

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