diff options
| author | Paul Eggert | 2020-05-19 23:22:40 -0700 |
|---|---|---|
| committer | Paul Eggert | 2020-05-19 23:25:16 -0700 |
| commit | f0b0105d913a94c66f230874c9269b19dbbc83bd (patch) | |
| tree | 21180d9cd9266d18187e8dd4de487eed950efa14 /src/alloc.c | |
| parent | 5352bda4eeb7415ad2bda5d74e007b4f36021e68 (diff) | |
| download | emacs-f0b0105d913a94c66f230874c9269b19dbbc83bd.tar.gz emacs-f0b0105d913a94c66f230874c9269b19dbbc83bd.zip | |
Hoist some byte-code checking out of eval
Check Lisp_Compiled objects better as they’re created,
so that the byte-code interpreter needn’t do the checks
each time it executes them. This improved performance
of ‘make compile-always’ by 1.5% on my platform. Also,
improve the quality of the (still-incomplete) checks, as
this is more practical now that they’re done less often.
* src/alloc.c (make_byte_code): Remove. All uses removed.
(Fmake_byte_code): Put a better (though still incomplete)
check here instead. Simplify by using Fvector instead
of make_uninit_vector followed by memcpy, and by using
XSETPVECTYPE instead of make_byte_code followed by XSETCOMPILED.
* src/bytecode.c (Fbyte_code): Do sanity check and conditional
translation to unibyte here instead of each time the function is
executed.
(exec_byte_code): Omit no-longer-necessary sanity and
unibyte checking. Use SCHARS instead of SBYTES where
either will do, as SCHARS is faster.
* src/eval.c (fetch_and_exec_byte_code): New function.
(funcall_lambda): Use it.
(funcall_lambda, lambda_arity, Ffetch_bytecode):
Omit no-longer-necessary sanity checks.
(Ffetch_bytecode): Add sanity check if actually fetching.
* src/lisp.h (XSETCOMPILED): Remove. All uses removed.
* src/lread.c (read1): Check byte-code objects more thoroughly,
albeit still incompletely, and do translation to unibyte here
instead of each time the function is executed.
(read1): Use XSETPVECYPE instead of make_byte_code.
(read_vector): Omit no-longer-necessary sanity check.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 33 |
1 files changed, 10 insertions, 23 deletions
diff --git a/src/alloc.c b/src/alloc.c index ebc55857ea0..b7ebaa63a5b 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -3421,23 +3421,6 @@ usage: (vector &rest OBJECTS) */) | |||
| 3421 | return val; | 3421 | return val; |
| 3422 | } | 3422 | } |
| 3423 | 3423 | ||
| 3424 | void | ||
| 3425 | make_byte_code (struct Lisp_Vector *v) | ||
| 3426 | { | ||
| 3427 | /* Don't allow the global zero_vector to become a byte code object. */ | ||
| 3428 | eassert (0 < v->header.size); | ||
| 3429 | |||
| 3430 | if (v->header.size > 1 && STRINGP (v->contents[1]) | ||
| 3431 | && STRING_MULTIBYTE (v->contents[1])) | ||
| 3432 | /* BYTECODE-STRING must have been produced by Emacs 20.2 or the | ||
| 3433 | earlier because they produced a raw 8-bit string for byte-code | ||
| 3434 | and now such a byte-code string is loaded as multibyte while | ||
| 3435 | raw 8-bit characters converted to multibyte form. Thus, now we | ||
| 3436 | must convert them back to the original unibyte form. */ | ||
| 3437 | v->contents[1] = Fstring_as_unibyte (v->contents[1]); | ||
| 3438 | XSETPVECTYPE (v, PVEC_COMPILED); | ||
| 3439 | } | ||
| 3440 | |||
| 3441 | DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, | 3424 | DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, |
| 3442 | doc: /* Create a byte-code object with specified arguments as elements. | 3425 | doc: /* Create a byte-code object with specified arguments as elements. |
| 3443 | The arguments should be the ARGLIST, bytecode-string BYTE-CODE, constant | 3426 | The arguments should be the ARGLIST, bytecode-string BYTE-CODE, constant |
| @@ -3456,8 +3439,14 @@ stack before executing the byte-code. | |||
| 3456 | usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INTERACTIVE-SPEC &rest ELEMENTS) */) | 3439 | usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INTERACTIVE-SPEC &rest ELEMENTS) */) |
| 3457 | (ptrdiff_t nargs, Lisp_Object *args) | 3440 | (ptrdiff_t nargs, Lisp_Object *args) |
| 3458 | { | 3441 | { |
| 3459 | Lisp_Object val = make_uninit_vector (nargs); | 3442 | if (! ((FIXNUMP (args[COMPILED_ARGLIST]) |
| 3460 | struct Lisp_Vector *p = XVECTOR (val); | 3443 | || CONSP (args[COMPILED_ARGLIST]) |
| 3444 | || NILP (args[COMPILED_ARGLIST])) | ||
| 3445 | && STRINGP (args[COMPILED_BYTECODE]) | ||
| 3446 | && !STRING_MULTIBYTE (args[COMPILED_BYTECODE]) | ||
| 3447 | && VECTORP (args[COMPILED_CONSTANTS]) | ||
| 3448 | && FIXNATP (args[COMPILED_STACK_DEPTH]))) | ||
| 3449 | error ("Invalid byte-code object"); | ||
| 3461 | 3450 | ||
| 3462 | /* We used to purecopy everything here, if purify-flag was set. This worked | 3451 | /* We used to purecopy everything here, if purify-flag was set. This worked |
| 3463 | OK for Emacs-23, but with Emacs-24's lexical binding code, it can be | 3452 | OK for Emacs-23, but with Emacs-24's lexical binding code, it can be |
| @@ -3466,10 +3455,8 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 3466 | copied into pure space, including its free variables, which is sometimes | 3455 | copied into pure space, including its free variables, which is sometimes |
| 3467 | just wasteful and other times plainly wrong (e.g. those free vars may want | 3456 | just wasteful and other times plainly wrong (e.g. those free vars may want |
| 3468 | to be setcar'd). */ | 3457 | to be setcar'd). */ |
| 3469 | 3458 | Lisp_Object val = Fvector (nargs, args); | |
| 3470 | memcpy (p->contents, args, nargs * sizeof *args); | 3459 | XSETPVECTYPE (XVECTOR (val), PVEC_COMPILED); |
| 3471 | make_byte_code (p); | ||
| 3472 | XSETCOMPILED (val, p); | ||
| 3473 | return val; | 3460 | return val; |
| 3474 | } | 3461 | } |
| 3475 | 3462 | ||