[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. */
- branch scratch/bytecode-speedup created (now 712237cab6), Mattias Engdegård, 2022/01/11
- scratch/bytecode-speedup 1e439fe19a 10/11: Open-code aref and aset in bytecode interpreter, Mattias Engdegård, 2022/01/11
- scratch/bytecode-speedup 712237cab6 11/11: ; * lisp/emacs-lisp/byte-opt.el: Remove outdated comments, Mattias Engdegård, 2022/01/11
- scratch/bytecode-speedup 02ff30bfbb 06/11: ; * src/bytecode.c (exec_byte_code): Cosmetic improvement, Mattias Engdegård, 2022/01/11
- scratch/bytecode-speedup 09b5ed93b1 07/11: Remove nil check in exec_byte_code,
Mattias Engdegård <=
- scratch/bytecode-speedup 870806d4c4 04/11: Pin bytecode strings to avoid copy at call time, Mattias Engdegård, 2022/01/11
- scratch/bytecode-speedup 43932a0d90 01/11: Short-circuit the recursive bytecode funcall chain, Mattias Engdegård, 2022/01/11
- scratch/bytecode-speedup 5dd261282d 02/11: Inline fixnum operations in bytecode interpreter, Mattias Engdegård, 2022/01/11
- scratch/bytecode-speedup 1eacfb3c88 09/11: Remove the unused unbind-all bytecode, Mattias Engdegård, 2022/01/11
- scratch/bytecode-speedup b43e4a184f 03/11: Inline setcar and setcdr in byte-code interpreter, Mattias Engdegård, 2022/01/11
- scratch/bytecode-speedup 1dca615cf9 08/11: Move a runtime interpreter check to ENABLE_CHECKING, Mattias Engdegård, 2022/01/11
- scratch/bytecode-speedup a2b4058b96 05/11: Byte code arity check micro-optimisation, Mattias Engdegård, 2022/01/11