diff options
| author | Eli Zaretskii | 2023-02-17 16:15:51 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2023-02-17 16:15:51 +0200 |
| commit | 8aad8d75aa94d0d07f6abb0f0e04d7634d0d1d4a (patch) | |
| tree | 3340e204a463a2491ca43df815144d40e6f2b635 | |
| parent | d6e4f2437202f13bec85d68c003700d06aa343e6 (diff) | |
| download | emacs-8aad8d75aa94d0d07f6abb0f0e04d7634d0d1d4a.tar.gz emacs-8aad8d75aa94d0d07f6abb0f0e04d7634d0d1d4a.zip | |
; 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'.
| -rw-r--r-- | doc/lispref/compile.texi | 68 | ||||
| -rw-r--r-- | lisp/emacs-lisp/comp.el | 5 | ||||
| -rw-r--r-- | src/comp.c | 85 |
3 files changed, 113 insertions, 45 deletions
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 | |||
| 849 | of @code{user-emacs-directory} (@pxref{Init File}). You can do that | 849 | of @code{user-emacs-directory} (@pxref{Init File}). You can do that |
| 850 | by either changing the value of @code{native-comp-eln-load-path} | 850 | by either changing the value of @code{native-comp-eln-load-path} |
| 851 | (@pxref{Native-Compilation Variables}) or by temporarily pointing the | 851 | (@pxref{Native-Compilation Variables}) or by temporarily pointing the |
| 852 | @env{HOME} environment variable to a non-existing directory. | 852 | @env{HOME} environment variable to a non-existing directory. Note |
| 853 | that the latter technique might still produce a small number of | ||
| 854 | @file{*.eln} files if Emacs needs to generate @dfn{trampolines}, which | ||
| 855 | are used if Lisp primitives are advised or redefined in your Lisp code | ||
| 856 | that is being natively compiled. @xref{Native-Compilation Variables, | ||
| 857 | trampolines}. | ||
| 853 | 858 | ||
| 854 | @menu | 859 | @menu |
| 855 | * Native-Compilation Functions:: Functions to natively-compile Lisp. | 860 | * Native-Compilation Functions:: Functions to natively-compile Lisp. |
| @@ -1075,3 +1080,64 @@ The directories in this list are also used for writing the | |||
| 1075 | specifically, Emacs will write these files into the first writable | 1080 | specifically, Emacs will write these files into the first writable |
| 1076 | directory in the list. Thus, you can control where native-compilation | 1081 | directory in the list. Thus, you can control where native-compilation |
| 1077 | stores the results by changing the value of this variable. | 1082 | stores the results by changing the value of this variable. |
| 1083 | |||
| 1084 | @cindex disable asynchronous native compilation | ||
| 1085 | @cindex inhibit asynchronous native compilation | ||
| 1086 | @cindex asynchronous native compilation, disable | ||
| 1087 | @defvar native-comp-jit-compilation | ||
| 1088 | This variable, if non-@code{nil}, enables asynchronous (a.k.a.@: | ||
| 1089 | @dfn{just-in-time}, or @acronym{JIT}) native compilation of the | ||
| 1090 | @file{*.elc} files loaded by Emacs for which the corresponding | ||
| 1091 | @file{*.eln} files do not already exist. This JIT compilation uses | ||
| 1092 | separate Emacs sub-processes running in batch mode, according to the | ||
| 1093 | value of @code{native-comp-async-jobs-number}. When the JIT | ||
| 1094 | compilation of a Lisp file finishes successfully, the resulting | ||
| 1095 | @file{.eln} file is loaded and its code replaces the definition of | ||
| 1096 | functions provided by the @file{.elc} file. | ||
| 1097 | @end defvar | ||
| 1098 | |||
| 1099 | @cindex trampolines, in native compilation | ||
| 1100 | Setting the value of @code{native-comp-jit-compilation} to@code{nil} | ||
| 1101 | disables JIT native compilation. However, even when JIT native | ||
| 1102 | compilation is disabled, Emacs might still need to start asynchronous | ||
| 1103 | native compilation subprocesses to produce @dfn{trampolines}. To | ||
| 1104 | control this, use a separate variable, described below. | ||
| 1105 | |||
| 1106 | @defvar native-comp-enable-subr-trampolines | ||
| 1107 | This variable controls generation of trampolines. A trampoline is a | ||
| 1108 | small piece of native code required to allow calling Lisp primitives, | ||
| 1109 | which were advised or redefined, from Lisp code that was | ||
| 1110 | natively-compiled with @code{native-comp-speed} set to 2 or greater. | ||
| 1111 | Emacs stores the generated trampolines on separate @file{*.eln} files. | ||
| 1112 | By default, this variable's value is @code{t}, which enables the | ||
| 1113 | generation of trampoline files; setting it to @code{nil} disables the | ||
| 1114 | generation of trampolines. Note that if a trampoline needed for | ||
| 1115 | advising or redefining a primitive is not available and cannot be | ||
| 1116 | generated, calls to that primitive from natively-compiled Lisp will | ||
| 1117 | ignore redefinitions and advices, and will behave as if the primitive | ||
| 1118 | was called directly from C. Therefore, we don't recommend disabling | ||
| 1119 | the trampoline generation, unless you know that all the trampolines | ||
| 1120 | needed by your Lisp programs are already compiled and accessible to | ||
| 1121 | Emacs. | ||
| 1122 | |||
| 1123 | The value of this variable can also be a string, in which case it is | ||
| 1124 | interpreted as the name of a directory in which to store the generated | ||
| 1125 | trampoline @file{*.eln} files, overriding the directories specified by | ||
| 1126 | @code{native-comp-eln-load-path}. This is useful if you want the | ||
| 1127 | trampolines to be generated as needed, but don't want to store them | ||
| 1128 | under the user's @env{HOME} directory or the other public directories | ||
| 1129 | where @file{*.eln} files are kept. However, unlike with directories | ||
| 1130 | in @code{native-comp-eln-load-path}, the trampolines will be stored in | ||
| 1131 | the directory given by the value of this variable, not in its | ||
| 1132 | version-specific subdirectory. | ||
| 1133 | |||
| 1134 | If this variable is non-@code{nil}, and Emacs needs to produce a | ||
| 1135 | trampoline, but it cannot find any writable directory to store the | ||
| 1136 | trampoline, it will store it inside @code{temporary-file-directory} | ||
| 1137 | (@pxref{Unique File Names}). | ||
| 1138 | |||
| 1139 | Trampolines produced when no writable directory is found to store | ||
| 1140 | them, or when this variable is a string, will only be available for | ||
| 1141 | the duration of the current Emacs session, because Emacs doesn't look | ||
| 1142 | for trampolines in either of these places. | ||
| 1143 | @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." | |||
| 112 | "Primitive functions to exclude from trampoline optimization. | 112 | "Primitive functions to exclude from trampoline optimization. |
| 113 | 113 | ||
| 114 | Primitive functions included in this list will not be called | 114 | Primitive functions included in this list will not be called |
| 115 | directly by the native code being compiled, this makes | 115 | directly by the natively-compiled code, which makes trampolines for |
| 116 | tranpolines for those primitives not necessary in case of | 116 | those primitives unnecessary in case of function redefinition/advice." |
| 117 | function redefinition/advise." | ||
| 118 | :type '(repeat symbol) | 117 | :type '(repeat symbol) |
| 119 | :version "28.1") | 118 | :version "28.1") |
| 120 | 119 | ||
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) | |||
| 5670 | { | 5670 | { |
| 5671 | #ifdef HAVE_NATIVE_COMP | 5671 | #ifdef HAVE_NATIVE_COMP |
| 5672 | DEFVAR_LISP ("comp--delayed-sources", Vcomp__delayed_sources, | 5672 | DEFVAR_LISP ("comp--delayed-sources", Vcomp__delayed_sources, |
| 5673 | doc: /* List of sources to be native-compiled when startup is finished. | 5673 | doc: /* List of sources to be native-compiled when startup is finished. |
| 5674 | For internal use. */); | 5674 | For internal use. */); |
| 5675 | DEFVAR_BOOL ("comp--compilable", | 5675 | DEFVAR_BOOL ("comp--compilable", comp__compilable, |
| 5676 | comp__compilable, | 5676 | doc: /* Non-nil when comp.el can be native compiled. |
| 5677 | doc: /* Non-nil when comp.el can be native compiled. | ||
| 5678 | For internal use. */); | 5677 | For internal use. */); |
| 5679 | /* Compiler control customizes. */ | 5678 | /* Compiler control customizes. */ |
| 5680 | DEFVAR_BOOL ("native-comp-jit-compilation", | 5679 | DEFVAR_BOOL ("native-comp-jit-compilation", native_comp_jit_compilation, |
| 5681 | native_comp_jit_compilation, | 5680 | doc: /* If non-nil, compile loaded .elc files asynchronously. |
| 5682 | doc: /* If non-nil compile loaded .elc files asynchronously. | ||
| 5683 | 5681 | ||
| 5684 | After compilation, each function definition is updated to the native | 5682 | After compilation, each function definition is updated to use the |
| 5685 | compiled one. */); | 5683 | natively-compiled one. */); |
| 5686 | native_comp_jit_compilation = true; | 5684 | native_comp_jit_compilation = true; |
| 5687 | 5685 | ||
| 5688 | DEFSYM (Qnative_comp_speed, "native-comp-speed"); | 5686 | DEFSYM (Qnative_comp_speed, "native-comp-speed"); |
| @@ -5827,31 +5825,34 @@ compiled one. */); | |||
| 5827 | /* FIXME should be initialized but not here... Plus this don't have | 5825 | /* FIXME should be initialized but not here... Plus this don't have |
| 5828 | to be necessarily exposed to lisp but can easy debug for now. */ | 5826 | to be necessarily exposed to lisp but can easy debug for now. */ |
| 5829 | DEFVAR_LISP ("comp-subr-list", Vcomp_subr_list, | 5827 | DEFVAR_LISP ("comp-subr-list", Vcomp_subr_list, |
| 5830 | doc: /* List of all defined subrs. */); | 5828 | doc: /* List of all defined subrs. */); |
| 5831 | DEFVAR_LISP ("comp-abi-hash", Vcomp_abi_hash, | 5829 | DEFVAR_LISP ("comp-abi-hash", Vcomp_abi_hash, |
| 5832 | doc: /* String signing the .eln files ABI. */); | 5830 | doc: /* String signing the .eln files ABI. */); |
| 5833 | Vcomp_abi_hash = Qnil; | 5831 | Vcomp_abi_hash = Qnil; |
| 5834 | DEFVAR_LISP ("comp-native-version-dir", Vcomp_native_version_dir, | 5832 | DEFVAR_LISP ("comp-native-version-dir", Vcomp_native_version_dir, |
| 5835 | doc: /* Directory in use to disambiguate eln compatibility. */); | 5833 | doc: /* Directory in use to disambiguate eln compatibility. */); |
| 5836 | Vcomp_native_version_dir = Qnil; | 5834 | Vcomp_native_version_dir = Qnil; |
| 5837 | 5835 | ||
| 5838 | DEFVAR_LISP ("comp-deferred-pending-h", Vcomp_deferred_pending_h, | 5836 | DEFVAR_LISP ("comp-deferred-pending-h", Vcomp_deferred_pending_h, |
| 5839 | doc: /* Hash table symbol-name -> function-value. | 5837 | doc: /* Hash table symbol-name -> function-value. |
| 5840 | For internal use. */); | 5838 | For internal use. */); |
| 5841 | Vcomp_deferred_pending_h = CALLN (Fmake_hash_table, QCtest, Qeq); | 5839 | Vcomp_deferred_pending_h = CALLN (Fmake_hash_table, QCtest, Qeq); |
| 5842 | 5840 | ||
| 5843 | DEFVAR_LISP ("comp-eln-to-el-h", Vcomp_eln_to_el_h, | 5841 | DEFVAR_LISP ("comp-eln-to-el-h", Vcomp_eln_to_el_h, |
| 5844 | doc: /* Hash table eln-filename -> el-filename. */); | 5842 | doc: /* Hash table eln-filename -> el-filename. */); |
| 5845 | Vcomp_eln_to_el_h = CALLN (Fmake_hash_table, QCtest, Qequal); | 5843 | Vcomp_eln_to_el_h = CALLN (Fmake_hash_table, QCtest, Qequal); |
| 5846 | 5844 | ||
| 5847 | DEFVAR_LISP ("native-comp-eln-load-path", Vnative_comp_eln_load_path, | 5845 | DEFVAR_LISP ("native-comp-eln-load-path", Vnative_comp_eln_load_path, |
| 5848 | doc: /* List of eln cache directories. | 5846 | doc: /* List of directories to look for natively-compiled *.eln files. |
| 5849 | 5847 | ||
| 5850 | If a directory is non absolute it is assumed to be relative to | 5848 | The *.eln files are actually looked for in a version-specific |
| 5851 | `invocation-directory'. | 5849 | subdirectory of each directory in this list. That subdirectory |
| 5852 | `comp-native-version-dir' value is used as a sub-folder name inside | 5850 | is determined by the value of `comp-native-version-dir'. |
| 5853 | each eln cache directory. | 5851 | If the name of a directory in this list is not absolute, it is |
| 5854 | The last directory of this list is assumed to be the system one. */); | 5852 | assumed to be relative to `invocation-directory'. |
| 5853 | The last directory of this list is assumed to be the one holding | ||
| 5854 | the system *.eln files, which are the files produced when building | ||
| 5855 | Emacs. */); | ||
| 5855 | 5856 | ||
| 5856 | /* Temporary value in use for bootstrap. We can't do better as | 5857 | /* Temporary value in use for bootstrap. We can't do better as |
| 5857 | `invocation-directory' is still unset, will be fixed up during | 5858 | `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. */); | |||
| 5860 | 5861 | ||
| 5861 | DEFVAR_LISP ("native-comp-enable-subr-trampolines", | 5862 | DEFVAR_LISP ("native-comp-enable-subr-trampolines", |
| 5862 | Vnative_comp_enable_subr_trampolines, | 5863 | Vnative_comp_enable_subr_trampolines, |
| 5863 | doc: /* If non-nil, enable primitive trampoline synthesis. | 5864 | doc: /* If non-nil, enable generation of trampolines for calling primitives. |
| 5864 | This makes Emacs respect redefinition or advises of primitive functions | 5865 | Trampolines are needed so that Emacs respects redefinition or advice of |
| 5865 | when they are called from Lisp code natively-compiled at `native-comp-speed' | 5866 | primitive functions when they are called from Lisp code natively-compiled |
| 5866 | of 2. | 5867 | at `native-comp-speed' of 2. |
| 5867 | 5868 | ||
| 5868 | If `comp-enable-subr-trampolines' is a string it specifies a directory | 5869 | By default, the value is t, and when Emacs sees a redefined or advised |
| 5869 | in which to deposit the trampoline. | ||
| 5870 | |||
| 5871 | By default, this is enabled, and when Emacs sees a redefined or advised | ||
| 5872 | primitive called from natively-compiled Lisp, it generates a trampoline | 5870 | primitive called from natively-compiled Lisp, it generates a trampoline |
| 5873 | for it on-the-fly. | 5871 | for it on-the-fly. |
| 5874 | 5872 | ||
| 5875 | Disabling this, when a trampoline for a redefined or advised primitive is | 5873 | If the value is a file name (a string), it specifies the directory in |
| 5876 | not available from previous compilations, means that such redefinition | 5874 | which to deposit the generated trampolines, overriding the directories |
| 5877 | or advise will not have effect on calls from natively-compiled Lisp code. | 5875 | in `native-comp-eln-load-path'. |
| 5878 | That is, calls to primitives without existing trampolines from | 5876 | |
| 5879 | natively-compiled Lisp will behave as if the primitive was called | 5877 | When this variable is nil, generation of trampolines is disabled. |
| 5880 | directly from C. */); | 5878 | |
| 5879 | Disabling the generation of trampolines, when a trampoline for a redefined | ||
| 5880 | or advised primitive is not already available from previous compilations, | ||
| 5881 | means that such redefinition or advice will not have effect when calling | ||
| 5882 | primitives from natively-compiled Lisp code. That is, calls to primitives | ||
| 5883 | without existing trampolines from natively-compiled Lisp will behave as if | ||
| 5884 | the primitive was called directly from C, and will ignore its redefinition | ||
| 5885 | and advice. */); | ||
| 5881 | 5886 | ||
| 5882 | DEFVAR_LISP ("comp-installed-trampolines-h", Vcomp_installed_trampolines_h, | 5887 | DEFVAR_LISP ("comp-installed-trampolines-h", Vcomp_installed_trampolines_h, |
| 5883 | doc: /* Hash table subr-name -> installed trampoline. | 5888 | doc: /* Hash table subr-name -> installed trampoline. |
| 5884 | This is used to prevent double trampoline instantiation but also to | 5889 | This is used to prevent double trampoline instantiation, and also to |
| 5885 | protect the trampolines against GC. */); | 5890 | protect the trampolines against GC. */); |
| 5886 | Vcomp_installed_trampolines_h = CALLN (Fmake_hash_table); | 5891 | Vcomp_installed_trampolines_h = CALLN (Fmake_hash_table); |
| 5887 | 5892 | ||
| 5888 | DEFVAR_LISP ("comp-no-native-file-h", V_comp_no_native_file_h, | 5893 | DEFVAR_LISP ("comp-no-native-file-h", V_comp_no_native_file_h, |
| 5889 | doc: /* Files for which no deferred compilation has to be performed. | 5894 | doc: /* Files for which no deferred compilation should be performed. |
| 5890 | These files' compilation should not be deferred because the bytecode | 5895 | These files' compilation should not be deferred because the bytecode |
| 5891 | version was explicitly requested by the user during load. | 5896 | version was explicitly requested by the user during load. |
| 5892 | For internal use. */); | 5897 | For internal use. */); |
| 5893 | V_comp_no_native_file_h = CALLN (Fmake_hash_table, QCtest, Qequal); | 5898 | V_comp_no_native_file_h = CALLN (Fmake_hash_table, QCtest, Qequal); |
| 5894 | 5899 | ||
| 5895 | DEFVAR_BOOL ("comp-file-preloaded-p", comp_file_preloaded_p, | 5900 | DEFVAR_BOOL ("comp-file-preloaded-p", comp_file_preloaded_p, |
| 5896 | doc: /* When non-nil assume the file being compiled to | 5901 | doc: /* When non-nil, assume the file being compiled to be preloaded. */); |
| 5897 | be preloaded. */); | ||
| 5898 | 5902 | ||
| 5899 | DEFVAR_LISP ("comp-loaded-comp-units-h", Vcomp_loaded_comp_units_h, | 5903 | DEFVAR_LISP ("comp-loaded-comp-units-h", Vcomp_loaded_comp_units_h, |
| 5900 | doc: /* Hash table recording all loaded compilation units. | 5904 | doc: /* Hash table recording all loaded compilation units, file -> CU. */); |
| 5901 | file -> CU. */); | ||
| 5902 | Vcomp_loaded_comp_units_h = | 5905 | Vcomp_loaded_comp_units_h = |
| 5903 | CALLN (Fmake_hash_table, QCweakness, Qvalue, QCtest, Qequal); | 5906 | CALLN (Fmake_hash_table, QCweakness, Qvalue, QCtest, Qequal); |
| 5904 | 5907 | ||