From: Eli Zaretskii Date: Fri, 17 Feb 2023 14:15:51 +0000 (+0200) Subject: ; Improve and update documentation of native compilation X-Git-Tag: emacs-29.0.90~425 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=8aad8d75aa94d0d07f6abb0f0e04d7634d0d1d4a;p=emacs.git ; Improve and update documentation of native compilation * src/comp.c (syms_of_comp) : 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'. --- diff --git a/doc/lispref/compile.texi b/doc/lispref/compile.texi index 0617b9c533c..cdbf64036da 100644 --- a/doc/lispref/compile.texi +++ b/doc/lispref/compile.texi @@ -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 diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el index a6b9b3f57ea..2d9cad6d98c 100644 --- a/lisp/emacs-lisp/comp.el +++ b/lisp/emacs-lisp/comp.el @@ -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") diff --git a/src/comp.c b/src/comp.c index 019d1e78fff..beaf443a0f7 100644 --- a/src/comp.c +++ b/src/comp.c @@ -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);