; 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

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
by either changing the value of @code{native-comp-eln-load-path}
(@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
* 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
directory in the list. Thus, you can control where native-compilation
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 included in this list will not be called
directly by the native code being compiled, this makes
tranpolines for those primitives not necessary in case of
function redefinition/advise."
directly by the natively-compiled code, which makes trampolines for
those primitives unnecessary in case of function redefinition/advice."
:type '(repeat symbol)
:version "28.1")

View file

@ -5670,19 +5670,17 @@ syms_of_comp (void)
{
#ifdef HAVE_NATIVE_COMP
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. */);
DEFVAR_BOOL ("comp--compilable",
comp__compilable,
doc: /* Non-nil when comp.el can be native compiled.
DEFVAR_BOOL ("comp--compilable", comp__compilable,
doc: /* Non-nil when comp.el can be native compiled.
For internal use. */);
/* Compiler control customizes. */
DEFVAR_BOOL ("native-comp-jit-compilation",
native_comp_jit_compilation,
doc: /* If non-nil compile loaded .elc files asynchronously.
DEFVAR_BOOL ("native-comp-jit-compilation", native_comp_jit_compilation,
doc: /* If non-nil, compile loaded .elc files asynchronously.
After compilation, each function definition is updated to the native
compiled one. */);
After compilation, each function definition is updated to use the
natively-compiled one. */);
native_comp_jit_compilation = true;
DEFSYM (Qnative_comp_speed, "native-comp-speed");
@ -5827,31 +5825,34 @@ compiled one. */);
/* FIXME should be initialized but not here... Plus this don't have
to be necessarily exposed to lisp but can easy debug for now. */
DEFVAR_LISP ("comp-subr-list", Vcomp_subr_list,
doc: /* List of all defined subrs. */);
doc: /* List of all defined subrs. */);
DEFVAR_LISP ("comp-abi-hash", Vcomp_abi_hash,
doc: /* String signing the .eln files ABI. */);
doc: /* String signing the .eln files ABI. */);
Vcomp_abi_hash = Qnil;
DEFVAR_LISP ("comp-native-version-dir", Vcomp_native_version_dir,
doc: /* Directory in use to disambiguate eln compatibility. */);
doc: /* Directory in use to disambiguate eln compatibility. */);
Vcomp_native_version_dir = Qnil;
DEFVAR_LISP ("comp-deferred-pending-h", Vcomp_deferred_pending_h,
doc: /* Hash table symbol-name -> function-value.
doc: /* Hash table symbol-name -> function-value.
For internal use. */);
Vcomp_deferred_pending_h = CALLN (Fmake_hash_table, QCtest, Qeq);
DEFVAR_LISP ("comp-eln-to-el-h", Vcomp_eln_to_el_h,
doc: /* Hash table eln-filename -> el-filename. */);
doc: /* Hash table eln-filename -> el-filename. */);
Vcomp_eln_to_el_h = CALLN (Fmake_hash_table, QCtest, Qequal);
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
`invocation-directory'.
`comp-native-version-dir' value is used as a sub-folder name inside
each eln cache directory.
The last directory of this list is assumed to be the system one. */);
The *.eln files are actually looked for in a version-specific
subdirectory of each directory in this list. That subdirectory
is determined by the value of `comp-native-version-dir'.
If the name of a directory in this list is not absolute, it is
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
`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",
Vnative_comp_enable_subr_trampolines,
doc: /* If non-nil, enable primitive trampoline synthesis.
This makes Emacs respect redefinition or advises of primitive functions
when they are called from Lisp code natively-compiled at `native-comp-speed'
of 2.
doc: /* If non-nil, enable generation of trampolines for calling primitives.
Trampolines are needed so that Emacs respects redefinition or advice of
primitive functions when they are called from Lisp code natively-compiled
at `native-comp-speed' of 2.
If `comp-enable-subr-trampolines' is a string it specifies a directory
in which to deposit the trampoline.
By default, this is enabled, and when Emacs sees a redefined or advised
By default, the value is t, and when Emacs sees a redefined or advised
primitive called from natively-compiled Lisp, it generates a trampoline
for it on-the-fly.
Disabling this, when a trampoline for a redefined or advised primitive is
not available from previous compilations, means that such redefinition
or advise will not have effect on calls 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. */);
If the value is a file name (a string), it specifies the directory in
which to deposit the generated trampolines, overriding the directories
in `native-comp-eln-load-path'.
When this variable is nil, generation of trampolines is disabled.
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,
doc: /* Hash table subr-name -> installed trampoline.
This is used to prevent double trampoline instantiation but also to
doc: /* Hash table subr-name -> installed trampoline.
This is used to prevent double trampoline instantiation, and also to
protect the trampolines against GC. */);
Vcomp_installed_trampolines_h = CALLN (Fmake_hash_table);
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
version was explicitly requested by the user during load.
For internal use. */);
V_comp_no_native_file_h = CALLN (Fmake_hash_table, QCtest, Qequal);
DEFVAR_BOOL ("comp-file-preloaded-p", comp_file_preloaded_p,
doc: /* When non-nil assume the file being compiled to
be preloaded. */);
doc: /* When non-nil, assume the file being compiled to be preloaded. */);
DEFVAR_LISP ("comp-loaded-comp-units-h", Vcomp_loaded_comp_units_h,
doc: /* Hash table recording all loaded compilation units.
file -> CU. */);
doc: /* Hash table recording all loaded compilation units, file -> CU. */);
Vcomp_loaded_comp_units_h =
CALLN (Fmake_hash_table, QCweakness, Qvalue, QCtest, Qequal);