diff options
| author | Mattias EngdegÄrd | 2021-02-21 15:24:41 +0100 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2021-02-21 21:58:25 +0100 |
| commit | d0c47652e527397cae96444c881bf60455c763c1 (patch) | |
| tree | 9dfa3ce23f5251726ebd287298486667a135101b /src/alloc.c | |
| parent | 2790c6a572a905359c60f055c682b28ef5c8ff0d (diff) | |
| download | emacs-d0c47652e527397cae96444c881bf60455c763c1.tar.gz emacs-d0c47652e527397cae96444c881bf60455c763c1.zip | |
Faster, more compact, and readable closure creation
Simplify closure creation by calling a single function at run time
instead of putting it together from small pieces. This is faster
(by about a factor 2), takes less space on disk and in memory, and
makes internal functions somewhat readable in disassembly listings again.
This is done by creating a prototype function at compile-time whose
closure variables are placeholder values V0, V1... which can be seen
in the disassembly. The prototype is then cloned at run time using
the new make-closure function that replaces the placeholders with
the actual closure variables.
* lisp/emacs-lisp/bytecomp.el (byte-compile-make-closure):
Generate call to make-closure from a prototype function.
* src/alloc.c (Fmake_closure): New function.
(syms_of_alloc): Defsubr it.
* src/data.c (syms_of_data): Defsym byte-code-function-p.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/alloc.c b/src/alloc.c index b86ed4ed262..e72fc4c4332 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -3498,6 +3498,38 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH &optional DOCSTRING INT | |||
| 3498 | return val; | 3498 | return val; |
| 3499 | } | 3499 | } |
| 3500 | 3500 | ||
| 3501 | DEFUN ("make-closure", Fmake_closure, Smake_closure, 1, MANY, 0, | ||
| 3502 | doc: /* Create a byte-code closure from PROTOTYPE and CLOSURE-VARS. | ||
| 3503 | Return a copy of PROTOTYPE, a byte-code object, with CLOSURE-VARS | ||
| 3504 | replacing the elements in the beginning of the constant-vector. | ||
| 3505 | usage: (make-closure PROTOTYPE &rest CLOSURE-VARS) */) | ||
| 3506 | (ptrdiff_t nargs, Lisp_Object *args) | ||
| 3507 | { | ||
| 3508 | Lisp_Object protofun = args[0]; | ||
| 3509 | CHECK_TYPE (COMPILEDP (protofun), Qbyte_code_function_p, protofun); | ||
| 3510 | |||
| 3511 | /* Create a copy of the constant vector, filling it with the closure | ||
| 3512 | variables in the beginning. (The overwritten part should just | ||
| 3513 | contain placeholder values.) */ | ||
| 3514 | Lisp_Object proto_constvec = AREF (protofun, COMPILED_CONSTANTS); | ||
| 3515 | ptrdiff_t constsize = ASIZE (proto_constvec); | ||
| 3516 | ptrdiff_t nvars = nargs - 1; | ||
| 3517 | if (nvars > constsize) | ||
| 3518 | error ("Closure vars do not fit in constvec"); | ||
| 3519 | Lisp_Object constvec = make_uninit_vector (constsize); | ||
| 3520 | memcpy (XVECTOR (constvec)->contents, args + 1, nvars * word_size); | ||
| 3521 | memcpy (XVECTOR (constvec)->contents + nvars, | ||
| 3522 | XVECTOR (proto_constvec)->contents + nvars, | ||
| 3523 | (constsize - nvars) * word_size); | ||
| 3524 | |||
| 3525 | /* Return a copy of the prototype function with the new constant vector. */ | ||
| 3526 | ptrdiff_t protosize = PVSIZE (protofun); | ||
| 3527 | struct Lisp_Vector *v = allocate_vectorlike (protosize, false); | ||
| 3528 | v->header = XVECTOR (protofun)->header; | ||
| 3529 | memcpy (v->contents, XVECTOR (protofun)->contents, protosize * word_size); | ||
| 3530 | v->contents[COMPILED_CONSTANTS] = constvec; | ||
| 3531 | return make_lisp_ptr (v, Lisp_Vectorlike); | ||
| 3532 | } | ||
| 3501 | 3533 | ||
| 3502 | 3534 | ||
| 3503 | /*********************************************************************** | 3535 | /*********************************************************************** |
| @@ -7573,6 +7605,7 @@ N should be nonnegative. */); | |||
| 7573 | defsubr (&Srecord); | 7605 | defsubr (&Srecord); |
| 7574 | defsubr (&Sbool_vector); | 7606 | defsubr (&Sbool_vector); |
| 7575 | defsubr (&Smake_byte_code); | 7607 | defsubr (&Smake_byte_code); |
| 7608 | defsubr (&Smake_closure); | ||
| 7576 | defsubr (&Smake_list); | 7609 | defsubr (&Smake_list); |
| 7577 | defsubr (&Smake_vector); | 7610 | defsubr (&Smake_vector); |
| 7578 | defsubr (&Smake_record); | 7611 | defsubr (&Smake_record); |