From 3224a443060a5f21bb910064fc06fe4432810355 Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Sun, 19 Jul 2020 10:46:24 +0200 Subject: [PATCH] Move eln files into dedicated cache directories When loading a elc file search for a corresponding eln one into `comp-eln-load-path' directories and load it if available. `comp-eln-load-path' contains by default two directory (user and system one). * src/pdumper.c (dump_do_dump_relocation): While resurrecting from load set eln cache sys dir in `Vcomp_eln_load_path'. * src/lread.c (maybe_swap_for_eln): New function. (Fload): Clean-up some now unnecessary code going back to the master one. (Fload): Make use of Vcomp_eln_to_el_h for the reverse file look-up. (openp_add_middle_dir_to_suffixes) (openp_max_middledir_and_suffix_len, openp_fill_filename_buffer): Remove functions. (openp): As for Fload revert code modifications. (openp): When a .elc file is being loaded check if a corresponding eln can be loaded in place. * src/comp.c (ELN_FILENAME_HASH_LEN): New macro. (comp_hash_string): New function. (hash_native_abi): Make use of 'comp_hash_string'. (hash_native_abi): Change `comp-native-path-postfix' format. (Fcomp_el_to_eln_filename): New function. (Fcomp__compile_ctxt_to_file): Have file_name as a input. (Vcomp_eln_to_el_h, Vcomp_eln_load_path): New global varaibles. * lisp/startup.el (normal-top-level): Add user eln cache directory in `comp-eln-load-path'. * lisp/help-fns.el (find-lisp-object-file-name): Reverse look-up files using `comp-eln-to-el-h'. * lisp/files.el (locate-file): Likewise. * lisp/emacs-lisp/find-func.el (find-library-name): Likewise. * lisp/emacs-lisp/comp.el (comp-output-directory) (comp-output-base-filename, comp-output-filename): Remove function. (comp-compile-ctxt-to-file): Create parent directories if necessary. (comp-run-async-workers, native-compile, native-compile-async): Make use `comp-el-to-eln-filename'. --- lisp/emacs-lisp/comp.el | 38 ++----- lisp/emacs-lisp/find-func.el | 6 +- lisp/files.el | 5 +- lisp/help-fns.el | 6 +- lisp/startup.el | 3 + src/comp.c | 71 ++++++++++-- src/lread.c | 206 ++++++++++++----------------------- src/pdumper.c | 17 ++- 8 files changed, 163 insertions(+), 189 deletions(-) diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el index a92392f63ac..30cedf298e2 100644 --- a/lisp/emacs-lisp/comp.el +++ b/lisp/emacs-lisp/comp.el @@ -569,28 +569,6 @@ VERBOSITY is a number between 0 and 3." -(defun comp-output-directory (src) - "Return the compilation direcotry for source SRC." - (let* ((src (if (symbolp src) (symbol-name src) src)) - (expanded-filename (expand-file-name src))) - (file-name-as-directory - (concat (file-name-directory expanded-filename) - comp-native-path-postfix)))) - -(defun comp-output-base-filename (src) - "Output filename sans extention for SRC file being native compiled." - (let* ((src (if (symbolp src) (symbol-name src) src)) - (expanded-filename (expand-file-name src)) - (output-dir (comp-output-directory src)) - (output-filename - (file-name-sans-extension - (file-name-nondirectory expanded-filename)))) - (expand-file-name output-filename output-dir))) - -(defun comp-output-filename (src) - "Output filename for SRC file being native compiled." - (concat (comp-output-base-filename src) ".eln")) - (defmacro comp-loop-insn-in-block (basic-block &rest body) "Loop over all insns in BASIC-BLOCK executning BODY. Inside BODY `insn' can be used to read or set the current @@ -2486,7 +2464,7 @@ Prepare every function for final compilation and drive the C back-end." (unless (file-exists-p dir) ;; In case it's created in the meanwhile. (ignore-error 'file-already-exists - (make-directory dir))) + (make-directory dir t))) (unless comp-dry-run (comp--compile-ctxt-to-file name)))) @@ -2597,7 +2575,7 @@ display a message." source-file) when (or comp-always-compile (file-newer-than-file-p source-file - (comp-output-filename source-file))) + (comp-el-to-eln-filename source-file))) do (let* ((expr `(progn (require 'comp) (setf comp-speed ,comp-speed @@ -2636,7 +2614,7 @@ display a message." (when (and load1 (zerop (process-exit-status process))) (native-elisp-load - (comp-output-filename source-file1) + (comp-el-to-eln-filename source-file1) (eq load1 'late))) (comp-run-async-workers))))) (puthash source-file process comp-async-compilations)) @@ -2676,7 +2654,11 @@ Return the compilation unit file name." (byte-compile-debug t) (comp-ctxt (make-comp-ctxt - :output (comp-output-base-filename function-or-file) + :output (comp-el-to-eln-filename (if (symbolp function-or-file) + (symbol-name function-or-file) + function-or-file) + (when byte-native-for-bootstrap + (car (last comp-eln-load-path)))) :with-late-load with-late-load))) (comp-log "\n \n" 1) (condition-case err @@ -2770,8 +2752,8 @@ queued with LOAD %" (and (eq load 'late) (cl-some (lambda (re) (string-match re file)) comp-deferred-compilation-black-list))) - (let ((out-dir (comp-output-directory file)) - (out-filename (comp-output-filename file))) + (let* ((out-filename (comp-el-to-eln-filename file)) + (out-dir (file-name-directory out-filename))) (if (or (file-writable-p out-filename) (and (not (file-exists-p out-dir)) (file-writable-p (substring out-dir 0 -1)))) diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el index efbcfb3a722..2db976f8c5c 100644 --- a/lisp/emacs-lisp/find-func.el +++ b/lisp/emacs-lisp/find-func.el @@ -188,11 +188,7 @@ LIBRARY should be a string (the name of the library)." ((string-match "\\.el\\(c\\(\\..*\\)?\\)\\'" library) (setq library (replace-match "" t t library))) ((string-match "\\.eln\\'" library) - ;; From help-fns.el. - (setq library (expand-file-name (concat (file-name-base library) - ".el") - (concat (file-name-directory library) - ".."))))) + (setq library (gethash (file-name-nondirectory library) comp-eln-to-el-h)))) (or (locate-file library (or find-function-source-path load-path) diff --git a/lisp/files.el b/lisp/files.el index 9270f334afa..2aeae0a9bef 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -926,7 +926,10 @@ one or more of those symbols." (logior (if (memq 'executable predicate) 1 0) (if (memq 'writable predicate) 2 0) (if (memq 'readable predicate) 4 0)))) - (locate-file-internal filename path suffixes predicate)) + (let ((file (locate-file-internal filename path suffixes predicate))) + (if (and file (string-match "\\.eln\\'" file)) + (gethash (file-name-nondirectory file) comp-eln-to-el-h) + file))) (defun locate-file-completion-table (dirs suffixes string pred action) "Do completion for file names passed to `locate-file'." diff --git a/lisp/help-fns.el b/lisp/help-fns.el index afca2cd932e..49cdb4ed5e4 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -333,10 +333,8 @@ suitable file is found, return nil." object (or (if (symbolp type) type) 'defun)))) (file-name (if (and true-name (string-match "[.]eln\\'" true-name)) - (expand-file-name (concat (file-name-base true-name) - ".el") - (concat (file-name-directory true-name) - "..")) + (gethash (file-name-nondirectory true-name) + comp-eln-to-el-h) true-name))) (cond (autoloaded diff --git a/lisp/startup.el b/lisp/startup.el index e58f27e7ebc..e469b90bd68 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -537,6 +537,9 @@ It is the default value of the variable `top-level'." (setq user-emacs-directory (startup--xdg-or-homedot startup--xdg-config-home-emacs nil)) + (when (boundp 'comp-eln-load-path) + (setq comp-eln-load-path (cons (concat user-emacs-directory "eln-cache/") + comp-eln-load-path))) ;; Look in each dir in load-path for a subdirs.el file. If we ;; find one, load it, which will add the appropriate subdirs of ;; that dir into load-path. This needs to be done before setting diff --git a/src/comp.c b/src/comp.c index 704bd4b6b35..9582506f91b 100644 --- a/src/comp.c +++ b/src/comp.c @@ -393,6 +393,8 @@ load_gccjit_if_necessary (bool mandatory) } +#define ELN_FILENAME_HASH_LEN 64 + /* C symbols emitted for the load relocation mechanism. */ #define CURRENT_THREAD_RELOC_SYM "current_thread_reloc" #define PURE_RELOC_SYM "pure_reloc" @@ -634,6 +636,16 @@ format_string (const char *format, ...) return scratch_area; } +static Lisp_Object +comp_hash_string (Lisp_Object string) +{ + Lisp_Object digest = make_uninit_string (SHA512_DIGEST_SIZE * 2); + sha512_buffer (SSDATA (string), SCHARS (string), SSDATA (digest)); + hexbuf_digest (SSDATA (digest), SDATA (digest), SHA512_DIGEST_SIZE); + + return digest; +} + /* Produce a key hashing Vcomp_subr_list. */ void @@ -641,10 +653,7 @@ hash_native_abi (void) { Lisp_Object string = Fmapconcat (intern_c_string ("subr-name"), Vcomp_subr_list, build_string (" ")); - Lisp_Object digest = make_uninit_string (SHA512_DIGEST_SIZE * 2); - - sha512_buffer (SSDATA (string), SCHARS (string), SSDATA (digest)); - hexbuf_digest (SSDATA (digest), SDATA (digest), SHA512_DIGEST_SIZE); + Lisp_Object digest = comp_hash_string (string); /* Check runs once. */ eassert (NILP (Vcomp_abi_hash)); @@ -652,8 +661,7 @@ hash_native_abi (void) /* If 10 characters are usually sufficient for git I guess 16 are fine for us here. */ Vcomp_native_path_postfix = - concat3 (make_string ("eln-", 4), - Vsystem_configuration, + concat2 (Vsystem_configuration, concat2 (make_string ("-", 1), Fsubstring_no_properties (Vcomp_abi_hash, make_fixnum (0), @@ -3852,6 +3860,30 @@ compile_function (Lisp_Object func) /* Entry points exposed to lisp. */ /**********************************/ +DEFUN ("comp-el-to-eln-filename", Fcomp_el_to_eln_filename, + Scomp_el_to_eln_filename, 1, 2, 0, + doc: /* Given a source file return the corresponding .eln true filename. +If BASE-DIR is nil use the first entry in `comp-eln-load-path'. */) + (Lisp_Object file_name, Lisp_Object base_dir) +{ + CHECK_STRING (file_name); + file_name = Fexpand_file_name (file_name, Qnil); + Lisp_Object hashed = Fsubstring (comp_hash_string (file_name), Qnil, + make_fixnum (ELN_FILENAME_HASH_LEN)); + file_name = concat2 (Ffile_name_nondirectory (Fsubstring (file_name, Qnil, + make_fixnum (-3))), + build_string ("-")); + file_name = concat3 (file_name, hashed, build_string (NATIVE_ELISP_SUFFIX)); + if (NILP (base_dir)) + base_dir = XCAR (Vcomp_eln_load_path); + + if (!file_name_absolute_p (SSDATA (base_dir))) + base_dir = Fexpand_file_name (base_dir, Vinvocation_directory); + + return Fexpand_file_name (file_name, + concat2 (base_dir, Vcomp_native_path_postfix)); +} + DEFUN ("comp--init-ctxt", Fcomp__init_ctxt, Scomp__init_ctxt, 0, 0, 0, doc: /* Initialize the native compiler context. Return t on success. */) @@ -4039,11 +4071,12 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file, Scomp__compile_ctxt_to_file, 1, 1, 0, doc: /* Compile as native code the current context to file. */) - (Lisp_Object base_name) + (Lisp_Object file_name) { load_gccjit_if_necessary (true); - CHECK_STRING (base_name); + CHECK_STRING (file_name); + Lisp_Object base_name = Fsubstring (file_name, Qnil, make_fixnum (-4)); gcc_jit_context_set_int_option (comp.ctxt, GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, @@ -4105,19 +4138,18 @@ DEFUN ("comp--compile-ctxt-to-file", Fcomp__compile_ctxt_to_file, AUTO_STRING (dot_so, NATIVE_ELISP_SUFFIX); - Lisp_Object out_file = CALLN (Fconcat, base_name, dot_so); Lisp_Object tmp_file = Fmake_temp_file_internal (base_name, Qnil, dot_so, Qnil); gcc_jit_context_compile_to_file (comp.ctxt, GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY, SSDATA (tmp_file)); - CALL2I (comp--replace-output-file, out_file, tmp_file); + CALL2I (comp--replace-output-file, file_name, tmp_file); if (!noninteractive) unbind_to (count, Qnil); - return out_file; + return file_name; } DEFUN ("comp-libgccjit-version", Fcomp_libgccjit_version, @@ -4971,6 +5003,7 @@ syms_of_comp (void) build_pure_c_string ("eln file inconsistent with current runtime " "configuration, please recompile")); + defsubr (&Scomp_el_to_eln_filename); defsubr (&Scomp__init_ctxt); defsubr (&Scomp__release_ctxt); defsubr (&Scomp__compile_ctxt_to_file); @@ -5015,6 +5048,22 @@ syms_of_comp (void) internal use during */); 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. */); + Vcomp_eln_to_el_h = CALLN (Fmake_hash_table, QCtest, Qequal); + + DEFVAR_LISP ("comp-eln-load-path", Vcomp_eln_load_path, + doc: /* List of eln cache directories. + +If a directory is non absolute is assumed to be relative to +`invocation-directory'. +The last directory of this list is assumed to be the system one. */); + + /* Temporary value in use for boostrap. We can't do better as + `invocation-directory' is still unset, will be fixed up during + dump reload. */ + Vcomp_eln_load_path = Fcons (build_string ("../eln-cache/"), Qnil); + #endif /* #ifdef HAVE_NATIVE_COMP */ defsubr (&Snative_comp_available_p); diff --git a/src/lread.c b/src/lread.c index f10a20ded86..c5bec0633df 100644 --- a/src/lread.c +++ b/src/lread.c @@ -1231,8 +1231,7 @@ Return t if the file exists and loads successfully. */) suffixes = CALLN (Fappend, suffixes, Vload_file_rep_suffixes); } - fd = - openp (Vload_path, file, suffixes, &found, Qnil, load_prefer_newer); + fd = openp (Vload_path, file, suffixes, &found, Qnil, load_prefer_newer); } if (fd == -1) @@ -1478,9 +1477,8 @@ Return t if the file exists and loads successfully. */) same folder of their respective sources therfore not to break packages we fake `load-file-name' here. The non faked version of it is `load-true-file-name'. */ - specbind (Qload_file_name, - concat2 (parent_directory (Ffile_name_directory (found)), - Ffile_name_nondirectory (found))); + specbind (Qload_file_name, Fgethash (Ffile_name_nondirectory (found), + Vcomp_eln_to_el_h, Qnil)); } else specbind (Qload_file_name, found); @@ -1608,118 +1606,51 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */) return file; } -/* This function turns a list of suffixes into a list of middle dirs - and suffixes. If the suffix is not NATIVE_ELISP_SUFFIX then its - suffix is nil and it is added to the list as is. Instead, if it - suffix is NATIVE_ELISP_SUFFIX then two elements are added to the - list. The first one has middledir equal to nil and the second uses - comp-native-path-postfix as middledir. This is because we'd like - to search for dir/foo.eln before dir/middledir/foo.eln. +/* Look for a suitable .eln file to be loaded in place of FILENAME. + If found replace the content of FILENAME and FD. */ -For example, it turns this: - -(".eln" ".elc" ".elc.gz" ".el" ".el.gz") - - into this: - -((nil . ".eln") - (comp-native-path-postfix . ".eln") - (nil . ".elc") - (nil . ".elc.gz") - (nil . ".el") - (nil . ".el.gz")) -*/ -static Lisp_Object -openp_add_middle_dir_to_suffixes (Lisp_Object suffixes) +static void +maybe_swap_for_eln (Lisp_Object *filename, int *fd, struct timespec mtime) { - Lisp_Object tail = suffixes; - Lisp_Object extended_suf = Qnil; - FOR_EACH_TAIL_SAFE (tail) - { - /* suffixes may be a stack-based cons pointing to stack-based - strings. We must copy the suffix if we are putting it into - a heap-based cons to avoid a dangling reference. This would - lead to crashes during the GC. */ - CHECK_STRING_CAR (tail); - char * suf = SSDATA (XCAR (tail)); - Lisp_Object copied_suffix = build_string (suf); #ifdef HAVE_NATIVE_COMP - if (strcmp (NATIVE_ELISP_SUFFIX, suf) == 0) - { - CHECK_STRING (Vcomp_native_path_postfix); - /* Here we add them in the opposite order so that nreverse - corrects it. */ - extended_suf = Fcons (Fcons (Qnil, copied_suffix), extended_suf); - extended_suf = Fcons (Fcons (Vcomp_native_path_postfix, - copied_suffix), - extended_suf); - } - else -#endif - extended_suf = Fcons (Fcons (Qnil, copied_suffix), extended_suf); - } + struct stat eln_st; - suffixes = Fnreverse (extended_suf); - return suffixes; -} + if (!suffix_p (*filename, ".elc")) + return; -/* This function takes a list of middledirs and suffixes and returns - the maximum buffer space that this part of the filename will - need. */ -static ptrdiff_t -openp_max_middledir_and_suffix_len (Lisp_Object middledir_and_suffixes) -{ - ptrdiff_t max_extra_len = 0; - Lisp_Object tail = middledir_and_suffixes; - FOR_EACH_TAIL_SAFE (tail) + /* Search eln in the eln-cache directories. */ + Lisp_Object eln_path_tail = Vcomp_eln_load_path; + FOR_EACH_TAIL_SAFE (eln_path_tail) { - Lisp_Object middledir_and_suffix = XCAR (tail); - Lisp_Object middledir = XCAR (middledir_and_suffix); - Lisp_Object suffix = XCDR (middledir_and_suffix); - ptrdiff_t len = SBYTES (suffix); - if (!NILP (middledir)) - len += 2 + SBYTES (middledir); /* Add two slashes. */ - max_extra_len = max (max_extra_len, len); - } - return max_extra_len; -} + Lisp_Object el_name = + Fsubstring (*filename, Qnil, make_fixnum (-1)); + Lisp_Object eln_name = + Fcomp_el_to_eln_filename (el_name, XCAR (eln_path_tail)); + int eln_fd = emacs_open (SSDATA (ENCODE_FILE (eln_name)), O_RDONLY, 0); -/* This function completes the FN buffer with the middledir, - basenameme, and suffix. It takes the directory length in DIRNAME, - but it requires that it has been copied already to the start of - the buffer. - - After this function the FN buffer will be (depending on middledir) - dirname/middledir/basename.suffix - or - dirname/basename.suffix -*/ -static ptrdiff_t -openp_fill_filename_buffer (char *fn, ptrdiff_t dirnamelen, - Lisp_Object basenamewext, - Lisp_Object middledir_and_suffix) -{ - Lisp_Object middledir = XCAR (middledir_and_suffix); - Lisp_Object suffix = XCDR (middledir_and_suffix); - ptrdiff_t basenamewext_len = SBYTES (basenamewext); - ptrdiff_t fnlen, lsuffix = SBYTES (suffix); - ptrdiff_t lmiddledir = 0; - if (!NILP (middledir)) - { - /* Add 1 for the slash. */ - lmiddledir = SBYTES (middledir) + 1; - memcpy (fn + dirnamelen, SDATA (middledir), - lmiddledir - 1); - fn[dirnamelen + (lmiddledir - 1)] = '/'; + if (eln_fd > 0) + { + if (fstat (eln_fd, &eln_st) || S_ISDIR (eln_st.st_mode)) + emacs_close (eln_fd); + else + { + struct timespec eln_mtime = get_stat_mtime (&eln_st); + if (timespec_cmp (eln_mtime, mtime) > 0) + { + *filename = eln_name; + emacs_close (*fd); + *fd = eln_fd; + /* Store the eln -> el relation. */ + Fputhash (Ffile_name_nondirectory (eln_name), + el_name, Vcomp_eln_to_el_h); + return; + } + else + emacs_close (eln_fd); + } + } } - - memcpy (fn + dirnamelen + lmiddledir, SDATA (basenamewext), - basenamewext_len); - /* Make complete filename by appending SUFFIX. */ - memcpy (fn + dirnamelen + lmiddledir + basenamewext_len, - SDATA (suffix), lsuffix + 1); - fnlen = dirnamelen + lmiddledir + basenamewext_len + lsuffix; - return fnlen; +#endif } /* Search for a file whose name is STR, looking in directories @@ -1759,21 +1690,23 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, ptrdiff_t want_length; Lisp_Object filename; Lisp_Object string, tail, encoded_fn, save_string; - Lisp_Object middledir_and_suffixes; - ptrdiff_t max_extra_len = 0; + ptrdiff_t max_suffix_len = 0; int last_errno = ENOENT; int save_fd = -1; USE_SAFE_ALLOCA; - /* The last-modified time of the newest matching file found. Initialize it to something less than all valid timestamps. */ struct timespec save_mtime = make_timespec (TYPE_MINIMUM (time_t), -1); CHECK_STRING (str); - middledir_and_suffixes = openp_add_middle_dir_to_suffixes (suffixes); - - max_extra_len = openp_max_middledir_and_suffix_len (middledir_and_suffixes); + tail = suffixes; + FOR_EACH_TAIL_SAFE (tail) + { + CHECK_STRING_CAR (tail); + max_suffix_len = max (max_suffix_len, + SBYTES (XCAR (tail))); + } string = filename = encoded_fn = save_string = Qnil; @@ -1790,7 +1723,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, executable. */ FOR_EACH_TAIL_SAFE (path) { - ptrdiff_t dirnamelen, prefixlen; + ptrdiff_t baselen, prefixlen; if (EQ (path, just_use_str)) filename = str; @@ -1807,40 +1740,35 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, continue; } - /* Calculate maximum length of any filename made from this path element/specified file name and any possible suffix. */ - want_length = max_extra_len + SBYTES (filename); + want_length = max_suffix_len + SBYTES (filename); if (fn_size <= want_length) { fn_size = 100 + want_length; fn = SAFE_ALLOCA (fn_size); } - Lisp_Object dirnamewslash = Ffile_name_directory (filename); - Lisp_Object basenamewext = Ffile_name_nondirectory (filename); - /* Copy FILENAME's data to FN but remove starting /: if any. */ - prefixlen = ((SCHARS (dirnamewslash) > 2 - && SREF (dirnamewslash, 0) == '/' - && SREF (dirnamewslash, 1) == ':') + prefixlen = ((SCHARS (filename) > 2 + && SREF (filename, 0) == '/' + && SREF (filename, 1) == ':') ? 2 : 0); - dirnamelen = SBYTES (dirnamewslash) - prefixlen; - memcpy (fn, SDATA (dirnamewslash) + prefixlen, dirnamelen); + baselen = SBYTES (filename) - prefixlen; + memcpy (fn, SDATA (filename) + prefixlen, baselen); - /* Loop over middledir_and_suffixes. */ - AUTO_LIST1 (empty_string_only, Fcons (Qnil, empty_unibyte_string)); - tail = NILP (middledir_and_suffixes) ? empty_string_only - : middledir_and_suffixes; + /* Loop over suffixes. */ + AUTO_LIST1 (empty_string_only, empty_unibyte_string); + tail = NILP (suffixes) ? empty_string_only : suffixes; FOR_EACH_TAIL_SAFE (tail) { - Lisp_Object middledir_and_suffix = XCAR (tail); - Lisp_Object suffix = XCDR (middledir_and_suffix); + Lisp_Object suffix = XCAR (tail); + ptrdiff_t fnlen, lsuffix = SBYTES (suffix); Lisp_Object handler; - ptrdiff_t fnlen = openp_fill_filename_buffer (fn, dirnamelen, - basenamewext, - middledir_and_suffix); + /* Make complete filename by appending SUFFIX. */ + memcpy (fn + baselen, SDATA (suffix), lsuffix + 1); + fnlen = baselen + lsuffix; /* Check that the file exists and is not a directory. */ /* We used to only check for handlers on non-absolute file names: @@ -1962,9 +1890,11 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, } else { + maybe_swap_for_eln (&string, &fd, get_stat_mtime (&st)); /* We succeeded; return this descriptor and filename. */ if (storeptr) *storeptr = string; + SAFE_FREE (); return fd; } @@ -1973,6 +1903,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, /* No more suffixes. Return the newest. */ if (0 <= save_fd && ! CONSP (XCDR (tail))) { + maybe_swap_for_eln (&save_string, &save_fd, save_mtime); if (storeptr) *storeptr = save_string; SAFE_FREE (); @@ -5030,11 +4961,8 @@ to the specified file name if a suffix is allowed or required. */); Vload_suffixes = Fcons (build_pure_c_string (MODULES_SECONDARY_SUFFIX), Vload_suffixes); #endif -#endif -#ifdef HAVE_NATIVE_COMP - Vload_suffixes = Fcons (build_pure_c_string (NATIVE_ELISP_SUFFIX), Vload_suffixes); -#endif +#endif DEFVAR_LISP ("module-file-suffix", Vmodule_file_suffix, doc: /* Suffix of loadable module file, or nil if modules are not supported. */); #ifdef HAVE_MODULES diff --git a/src/pdumper.c b/src/pdumper.c index 629d0969346..ca055a1327c 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -5249,9 +5249,24 @@ dump_do_dump_relocation (const uintptr_t dump_base, { fclose (file); installation_state = INSTALLED; + /* FIXME Vcomp_eln_load_path = ?? */ } else - installation_state = LOCAL_BUILD; + { + installation_state = LOCAL_BUILD; + /* Fixup `comp-eln-load-path' so emacs can be invoked + position independently. */ + Lisp_Object eln_cache_sys = + Ffile_name_directory (concat2 (Vinvocation_directory, + XCDR (comp_u->file))); + /* One directory up... */ + eln_cache_sys = + Ffile_name_directory (Fsubstring (eln_cache_sys, Qnil, + make_fixnum (-1))); + /* FIXME for subsequent dumps we should fixup only the + last entry. */ + Vcomp_eln_load_path = Fcons (eln_cache_sys, Qnil); + } } comp_u->file = -- 2.39.5