emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

scratch/native-comp-eln-caches 2d9bd47 1/6: Move eln files into dedicate


From: Andrea Corallo
Subject: scratch/native-comp-eln-caches 2d9bd47 1/6: Move eln files into dedicated cache directories
Date: Sat, 15 Aug 2020 06:35:45 -0400 (EDT)

branch: scratch/native-comp-eln-caches
commit 2d9bd47587b9692de191d58cc5285e63628a6f3b
Author: Andrea Corallo <akrl@sdf.org>
Commit: Andrea Corallo <akrl@sdf.org>

    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 (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                   |  66 +++++++++++---
 src/lread.c                  | 200 +++++++++++--------------------------------
 src/pdumper.c                |  17 +++-
 8 files changed, 142 insertions(+), 199 deletions(-)

diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index a92392f..30cedf2 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 efbcfb3..2db976f 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 9270f33..2aeae0a 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 afca2cd..49cdb4e 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 e58f27e..e469b90 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 704bd4b..a31f2a8 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,27 @@ 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);
+
+  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 +4068,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 +4135,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 +5000,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 +5045,20 @@ 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.
+The last is assumed to be the system one.  */);
+  /* Temporary value in use for boostrap, will be fixed up during dump
+     reload.  */
+  Vcomp_eln_load_path =
+    Fcons (Ffile_name_as_directory (concat2 (Vinvocation_directory,
+                                            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 f5a7d44..4ab21ab 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,120 +1606,6 @@ 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.
-
-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)
-{
-  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);
-    }
-
-  suffixes = Fnreverse (extended_suf);
-  return suffixes;
-}
-
-/*  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)
-    {
-      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;
-}
-
-/*  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)] = '/';
-    }
-
-  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;
-}
-
 /* Search for a file whose name is STR, looking in directories
    in the Lisp list PATH, and trying suffixes from SUFFIX.
    On success, return a file descriptor (or 1 or -2 as described below).
@@ -1759,21 +1643,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 +1676,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 +1693,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:
@@ -1862,6 +1743,30 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object 
suffixes,
          string = make_unibyte_string (fn, fnlen);
        else
          string = make_string (fn, fnlen);
+#ifdef HAVE_NATIVE_COMP
+       if (suffix_p (string, ".elc"))
+         {
+           /* 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 el_name =
+                 Fsubstring (string, Qnil, make_fixnum (-1));
+               Lisp_Object eln_name =
+                 Fcomp_el_to_eln_filename (el_name, XCAR (eln_path_tail));
+               /* FIXME memoize using Fdirectory_files */
+               if (!NILP (Ffile_exists_p (eln_name))
+                   && !NILP (Ffile_newer_than_file_p (eln_name, string)))
+                 {
+                   string = eln_name;
+                   /* Store the eln -> el relation.  */
+                   Fputhash (Ffile_name_nondirectory (eln_name),
+                             el_name, Vcomp_eln_to_el_h);
+                   break;
+                 }
+             }
+         }
+#endif
        handler = Ffind_file_name_handler (string, Qfile_exists_p);
        if ((!NILP (handler) || (!NILP (predicate) && !EQ (predicate, Qt)))
            && !FIXNATP (predicate))
@@ -5030,11 +4935,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 629d096..ca055a1 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 =



reply via email to

[Prev in Thread] Current Thread [Next in Thread]