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/eval.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/eval.c')
| -rw-r--r-- | src/eval.c | 48 |
1 files changed, 19 insertions, 29 deletions
diff --git a/src/eval.c b/src/eval.c index 014905ce6df..be2af2d041b 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -2904,6 +2904,21 @@ funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *args) | |||
| 2904 | } | 2904 | } |
| 2905 | } | 2905 | } |
| 2906 | 2906 | ||
| 2907 | /* Call the compiled Lisp function FUN. If we have not yet read FUN's | ||
| 2908 | bytecode string and constants vector, fetch them from the file first. */ | ||
| 2909 | |||
| 2910 | static Lisp_Object | ||
| 2911 | fetch_and_exec_byte_code (Lisp_Object fun, Lisp_Object syms_left, | ||
| 2912 | ptrdiff_t nargs, Lisp_Object *args) | ||
| 2913 | { | ||
| 2914 | if (CONSP (AREF (fun, COMPILED_BYTECODE))) | ||
| 2915 | Ffetch_bytecode (fun); | ||
| 2916 | return exec_byte_code (AREF (fun, COMPILED_BYTECODE), | ||
| 2917 | AREF (fun, COMPILED_CONSTANTS), | ||
| 2918 | AREF (fun, COMPILED_STACK_DEPTH), | ||
| 2919 | syms_left, nargs, args); | ||
| 2920 | } | ||
| 2921 | |||
| 2907 | static Lisp_Object | 2922 | static Lisp_Object |
| 2908 | apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count) | 2923 | apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count) |
| 2909 | { | 2924 | { |
| @@ -2968,9 +2983,6 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, | |||
| 2968 | } | 2983 | } |
| 2969 | else if (COMPILEDP (fun)) | 2984 | else if (COMPILEDP (fun)) |
| 2970 | { | 2985 | { |
| 2971 | ptrdiff_t size = PVSIZE (fun); | ||
| 2972 | if (size <= COMPILED_STACK_DEPTH) | ||
| 2973 | xsignal1 (Qinvalid_function, fun); | ||
| 2974 | syms_left = AREF (fun, COMPILED_ARGLIST); | 2986 | syms_left = AREF (fun, COMPILED_ARGLIST); |
| 2975 | if (FIXNUMP (syms_left)) | 2987 | if (FIXNUMP (syms_left)) |
| 2976 | /* A byte-code object with an integer args template means we | 2988 | /* A byte-code object with an integer args template means we |
| @@ -2982,15 +2994,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, | |||
| 2982 | argument-binding code below instead (as do all interpreted | 2994 | argument-binding code below instead (as do all interpreted |
| 2983 | functions, even lexically bound ones). */ | 2995 | functions, even lexically bound ones). */ |
| 2984 | { | 2996 | { |
| 2985 | /* If we have not actually read the bytecode string | 2997 | return fetch_and_exec_byte_code (fun, syms_left, nargs, arg_vector); |
| 2986 | and constants vector yet, fetch them from the file. */ | ||
| 2987 | if (CONSP (AREF (fun, COMPILED_BYTECODE))) | ||
| 2988 | Ffetch_bytecode (fun); | ||
| 2989 | return exec_byte_code (AREF (fun, COMPILED_BYTECODE), | ||
| 2990 | AREF (fun, COMPILED_CONSTANTS), | ||
| 2991 | AREF (fun, COMPILED_STACK_DEPTH), | ||
| 2992 | syms_left, | ||
| 2993 | nargs, arg_vector); | ||
| 2994 | } | 2998 | } |
| 2995 | lexenv = Qnil; | 2999 | lexenv = Qnil; |
| 2996 | } | 3000 | } |
| @@ -3059,16 +3063,7 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, | |||
| 3059 | if (CONSP (fun)) | 3063 | if (CONSP (fun)) |
| 3060 | val = Fprogn (XCDR (XCDR (fun))); | 3064 | val = Fprogn (XCDR (XCDR (fun))); |
| 3061 | else | 3065 | else |
| 3062 | { | 3066 | val = fetch_and_exec_byte_code (fun, Qnil, 0, NULL); |
| 3063 | /* If we have not actually read the bytecode string | ||
| 3064 | and constants vector yet, fetch them from the file. */ | ||
| 3065 | if (CONSP (AREF (fun, COMPILED_BYTECODE))) | ||
| 3066 | Ffetch_bytecode (fun); | ||
| 3067 | val = exec_byte_code (AREF (fun, COMPILED_BYTECODE), | ||
| 3068 | AREF (fun, COMPILED_CONSTANTS), | ||
| 3069 | AREF (fun, COMPILED_STACK_DEPTH), | ||
| 3070 | Qnil, 0, 0); | ||
| 3071 | } | ||
| 3072 | 3067 | ||
| 3073 | return unbind_to (count, val); | 3068 | return unbind_to (count, val); |
| 3074 | } | 3069 | } |
| @@ -3153,9 +3148,6 @@ lambda_arity (Lisp_Object fun) | |||
| 3153 | } | 3148 | } |
| 3154 | else if (COMPILEDP (fun)) | 3149 | else if (COMPILEDP (fun)) |
| 3155 | { | 3150 | { |
| 3156 | ptrdiff_t size = PVSIZE (fun); | ||
| 3157 | if (size <= COMPILED_STACK_DEPTH) | ||
| 3158 | xsignal1 (Qinvalid_function, fun); | ||
| 3159 | syms_left = AREF (fun, COMPILED_ARGLIST); | 3151 | syms_left = AREF (fun, COMPILED_ARGLIST); |
| 3160 | if (FIXNUMP (syms_left)) | 3152 | if (FIXNUMP (syms_left)) |
| 3161 | return get_byte_code_arity (syms_left); | 3153 | return get_byte_code_arity (syms_left); |
| @@ -3198,13 +3190,11 @@ DEFUN ("fetch-bytecode", Ffetch_bytecode, Sfetch_bytecode, | |||
| 3198 | 3190 | ||
| 3199 | if (COMPILEDP (object)) | 3191 | if (COMPILEDP (object)) |
| 3200 | { | 3192 | { |
| 3201 | ptrdiff_t size = PVSIZE (object); | ||
| 3202 | if (size <= COMPILED_STACK_DEPTH) | ||
| 3203 | xsignal1 (Qinvalid_function, object); | ||
| 3204 | if (CONSP (AREF (object, COMPILED_BYTECODE))) | 3193 | if (CONSP (AREF (object, COMPILED_BYTECODE))) |
| 3205 | { | 3194 | { |
| 3206 | tem = read_doc_string (AREF (object, COMPILED_BYTECODE)); | 3195 | tem = read_doc_string (AREF (object, COMPILED_BYTECODE)); |
| 3207 | if (!CONSP (tem)) | 3196 | if (! (CONSP (tem) && STRINGP (XCAR (tem)) |
| 3197 | && VECTORP (XCDR (tem)))) | ||
| 3208 | { | 3198 | { |
| 3209 | tem = AREF (object, COMPILED_BYTECODE); | 3199 | tem = AREF (object, COMPILED_BYTECODE); |
| 3210 | if (CONSP (tem) && STRINGP (XCAR (tem))) | 3200 | if (CONSP (tem) && STRINGP (XCAR (tem))) |