; Improve and update documentation of native compilation

* src/comp.c (syms_of_comp) <native-comp-enable-subr-trampolines>
<native-comp-eln-load-path>: Doc fixes.

* lisp/emacs-lisp/comp.el (native-comp-never-optimize-functions):
Doc fix.

* doc/lispref/compile.texi (Native-Compilation Variables):
Document 'native-comp-jit-compilation' and
'native-comp-enable-subr-trampolines'.
This commit is contained in:
Eli Zaretskii 2023-02-17 16:15:51 +02:00
parent d6e4f24372
commit 8aad8d75aa
3 changed files with 113 additions and 45 deletions
doc/lispref
lisp/emacs-lisp
src

View file

@ -849,7 +849,12 @@ from writing its results, the @file{*.eln} files, into a subdirectory
of @code{user-emacs-directory} (@pxref{Init File}). You can do that of @code{user-emacs-directory} (@pxref{Init File}). You can do that
by either changing the value of @code{native-comp-eln-load-path} by either changing the value of @code{native-comp-eln-load-path}
(@pxref{Native-Compilation Variables}) or by temporarily pointing the (@pxref{Native-Compilation Variables}) or by temporarily pointing the
@env{HOME} environment variable to a non-existing directory. @env{HOME} environment variable to a non-existing directory. Note
that the latter technique might still produce a small number of
@file{*.eln} files if Emacs needs to generate @dfn{trampolines}, which
are used if Lisp primitives are advised or redefined in your Lisp code
that is being natively compiled. @xref{Native-Compilation Variables,
trampolines}.
@menu @menu
* Native-Compilation Functions:: Functions to natively-compile Lisp. * Native-Compilation Functions:: Functions to natively-compile Lisp.
@ -1075,3 +1080,64 @@ The directories in this list are also used for writing the
specifically, Emacs will write these files into the first writable specifically, Emacs will write these files into the first writable
directory in the list. Thus, you can control where native-compilation directory in the list. Thus, you can control where native-compilation
stores the results by changing the value of this variable. stores the results by changing the value of this variable.
@cindex disable asynchronous native compilation
@cindex inhibit asynchronous native compilation
@cindex asynchronous native compilation, disable
@defvar native-comp-jit-compilation
This variable, if non-@code{nil}, enables asynchronous (a.k.a.@:
@dfn{just-in-time}, or @acronym{JIT}) native compilation of the
@file{*.elc} files loaded by Emacs for which the corresponding
@file{*.eln} files do not already exist. This JIT compilation uses
separate Emacs sub-processes running in batch mode, according to the
value of @code{native-comp-async-jobs-number}. When the JIT
compilation of a Lisp file finishes successfully, the resulting
@file{.eln} file is loaded and its code replaces the definition of
functions provided by the @file{.elc} file.
@end defvar
@cindex trampolines, in native compilation
Setting the value of @code{native-comp-jit-compilation} to@code{nil}
disables JIT native compilation. However, even when JIT native
compilation is disabled, Emacs might still need to start asynchronous
native compilation subprocesses to produce @dfn{trampolines}. To
control this, use a separate variable, described below.
@defvar native-comp-enable-subr-trampolines
This variable controls generation of trampolines. A trampoline is a
small piece of native code required to allow calling Lisp primitives,
which were advised or redefined, from Lisp code that was
natively-compiled with @code{native-comp-speed} set to 2 or greater.
Emacs stores the generated trampolines on separate @file{*.eln} files.
By default, this variable's value is @code{t}, which enables the
generation of trampoline files; setting it to @code{nil} disables the
generation of trampolines. Note that if a trampoline needed for
advising or redefining a primitive is not available and cannot be
generated, calls to that primitive from natively-compiled Lisp will
ignore redefinitions and advices, and will behave as if the primitive
was called directly from C. Therefore, we don't recommend disabling
the trampoline generation, unless you know that all the trampolines
needed by your Lisp programs are already compiled and accessible to
Emacs.
The value of this variable can also be a string, in which case it is
interpreted as the name of a directory in which to store the generated
trampoline @file{*.eln} files, overriding the directories specified by
@code{native-comp-eln-load-path}. This is useful if you want the
trampolines to be generated as needed, but don't want to store them
under the user's @env{HOME} directory or the other public directories
where @file{*.eln} files are kept. However, unlike with directories
in @code{native-comp-eln-load-path}, the trampolines will be stored in
the directory given by the value of this variable, not in its
version-specific subdirectory.
If this variable is non-@code{nil}, and Emacs needs to produce a
trampoline, but it cannot find any writable directory to store the
trampoline, it will store it inside @code{temporary-file-directory}
(@pxref{Unique File Names}).
Trampolines produced when no writable directory is found to store
them, or when this variable is a string, will only be available for
the duration of the current Emacs session, because Emacs doesn't look
for trampolines in either of these places.
@end defvar

View file

@ -112,9 +112,8 @@ during bootstrap."
"Primitive functions to exclude from trampoline optimization. "Primitive functions to exclude from trampoline optimization.
Primitive functions included in this list will not be called Primitive functions included in this list will not be called
directly by the native code being compiled, this makes directly by the natively-compiled code, which makes trampolines for
tranpolines for those primitives not necessary in case of those primitives unnecessary in case of function redefinition/advice."
function redefinition/advise."
:type '(repeat symbol) :type '(repeat symbol)
:version "28.1") :version "28.1")

View file

@ -5672,17 +5672,15 @@ syms_of_comp (void)
DEFVAR_LISP ("comp--delayed-sources", Vcomp__delayed_sources, DEFVAR_LISP ("comp--delayed-sources", Vcomp__delayed_sources,
doc: /* List of sources to be native-compiled when startup is finished. doc: /* List of sources to be native-compiled when startup is finished.
For internal use. */); For internal use. */);
DEFVAR_BOOL ("comp--compilable", DEFVAR_BOOL ("comp--compilable", comp__compilable,
comp__compilable,
doc: /* Non-nil when comp.el can be native compiled. doc: /* Non-nil when comp.el can be native compiled.
For internal use. */); For internal use. */);
/* Compiler control customizes. */ /* Compiler control customizes. */
DEFVAR_BOOL ("native-comp-jit-compilation", DEFVAR_BOOL ("native-comp-jit-compilation", native_comp_jit_compilation,
native_comp_jit_compilation, doc: /* If non-nil, compile loaded .elc files asynchronously.
doc: /* If non-nil compile loaded .elc files asynchronously.
After compilation, each function definition is updated to the native After compilation, each function definition is updated to use the
compiled one. */); natively-compiled one. */);
native_comp_jit_compilation = true; native_comp_jit_compilation = true;
DEFSYM (Qnative_comp_speed, "native-comp-speed"); DEFSYM (Qnative_comp_speed, "native-comp-speed");
@ -5845,13 +5843,16 @@ For internal use. */);
Vcomp_eln_to_el_h = CALLN (Fmake_hash_table, QCtest, Qequal); Vcomp_eln_to_el_h = CALLN (Fmake_hash_table, QCtest, Qequal);
DEFVAR_LISP ("native-comp-eln-load-path", Vnative_comp_eln_load_path, DEFVAR_LISP ("native-comp-eln-load-path", Vnative_comp_eln_load_path,
doc: /* List of eln cache directories. doc: /* List of directories to look for natively-compiled *.eln files.
If a directory is non absolute it is assumed to be relative to The *.eln files are actually looked for in a version-specific
`invocation-directory'. subdirectory of each directory in this list. That subdirectory
`comp-native-version-dir' value is used as a sub-folder name inside is determined by the value of `comp-native-version-dir'.
each eln cache directory. If the name of a directory in this list is not absolute, it is
The last directory of this list is assumed to be the system one. */); assumed to be relative to `invocation-directory'.
The last directory of this list is assumed to be the one holding
the system *.eln files, which are the files produced when building
Emacs. */);
/* Temporary value in use for bootstrap. We can't do better as /* Temporary value in use for bootstrap. We can't do better as
`invocation-directory' is still unset, will be fixed up during `invocation-directory' is still unset, will be fixed up during
@ -5860,45 +5861,47 @@ The last directory of this list is assumed to be the system one. */);
DEFVAR_LISP ("native-comp-enable-subr-trampolines", DEFVAR_LISP ("native-comp-enable-subr-trampolines",
Vnative_comp_enable_subr_trampolines, Vnative_comp_enable_subr_trampolines,
doc: /* If non-nil, enable primitive trampoline synthesis. doc: /* If non-nil, enable generation of trampolines for calling primitives.
This makes Emacs respect redefinition or advises of primitive functions Trampolines are needed so that Emacs respects redefinition or advice of
when they are called from Lisp code natively-compiled at `native-comp-speed' primitive functions when they are called from Lisp code natively-compiled
of 2. at `native-comp-speed' of 2.
If `comp-enable-subr-trampolines' is a string it specifies a directory By default, the value is t, and when Emacs sees a redefined or advised
in which to deposit the trampoline.
By default, this is enabled, and when Emacs sees a redefined or advised
primitive called from natively-compiled Lisp, it generates a trampoline primitive called from natively-compiled Lisp, it generates a trampoline
for it on-the-fly. for it on-the-fly.
Disabling this, when a trampoline for a redefined or advised primitive is If the value is a file name (a string), it specifies the directory in
not available from previous compilations, means that such redefinition which to deposit the generated trampolines, overriding the directories
or advise will not have effect on calls from natively-compiled Lisp code. in `native-comp-eln-load-path'.
That is, calls to primitives without existing trampolines from
natively-compiled Lisp will behave as if the primitive was called When this variable is nil, generation of trampolines is disabled.
directly from C. */);
Disabling the generation of trampolines, when a trampoline for a redefined
or advised primitive is not already available from previous compilations,
means that such redefinition or advice will not have effect when calling
primitives from natively-compiled Lisp code. That is, calls to primitives
without existing trampolines from natively-compiled Lisp will behave as if
the primitive was called directly from C, and will ignore its redefinition
and advice. */);
DEFVAR_LISP ("comp-installed-trampolines-h", Vcomp_installed_trampolines_h, DEFVAR_LISP ("comp-installed-trampolines-h", Vcomp_installed_trampolines_h,
doc: /* Hash table subr-name -> installed trampoline. doc: /* Hash table subr-name -> installed trampoline.
This is used to prevent double trampoline instantiation but also to This is used to prevent double trampoline instantiation, and also to
protect the trampolines against GC. */); protect the trampolines against GC. */);
Vcomp_installed_trampolines_h = CALLN (Fmake_hash_table); Vcomp_installed_trampolines_h = CALLN (Fmake_hash_table);
DEFVAR_LISP ("comp-no-native-file-h", V_comp_no_native_file_h, DEFVAR_LISP ("comp-no-native-file-h", V_comp_no_native_file_h,
doc: /* Files for which no deferred compilation has to be performed. doc: /* Files for which no deferred compilation should be performed.
These files' compilation should not be deferred because the bytecode These files' compilation should not be deferred because the bytecode
version was explicitly requested by the user during load. version was explicitly requested by the user during load.
For internal use. */); For internal use. */);
V_comp_no_native_file_h = CALLN (Fmake_hash_table, QCtest, Qequal); V_comp_no_native_file_h = CALLN (Fmake_hash_table, QCtest, Qequal);
DEFVAR_BOOL ("comp-file-preloaded-p", comp_file_preloaded_p, DEFVAR_BOOL ("comp-file-preloaded-p", comp_file_preloaded_p,
doc: /* When non-nil assume the file being compiled to doc: /* When non-nil, assume the file being compiled to be preloaded. */);
be preloaded. */);
DEFVAR_LISP ("comp-loaded-comp-units-h", Vcomp_loaded_comp_units_h, DEFVAR_LISP ("comp-loaded-comp-units-h", Vcomp_loaded_comp_units_h,
doc: /* Hash table recording all loaded compilation units. doc: /* Hash table recording all loaded compilation units, file -> CU. */);
file -> CU. */);
Vcomp_loaded_comp_units_h = Vcomp_loaded_comp_units_h =
CALLN (Fmake_hash_table, QCweakness, Qvalue, QCtest, Qequal); CALLN (Fmake_hash_table, QCweakness, Qvalue, QCtest, Qequal);