aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNicolás Bértolo2020-05-25 18:05:23 -0300
committerAndrea Corallo2020-06-06 21:52:20 +0200
commite38678b268c2a3f77d1fa32a55706fb9e077405c (patch)
treef78ffbd5da5b17b5a827d18ee00b08ce59949cbf /src
parentee3df1483a9e733c27629da7bcf515789df52ef8 (diff)
downloademacs-e38678b268c2a3f77d1fa32a55706fb9e077405c.tar.gz
emacs-e38678b268c2a3f77d1fa32a55706fb9e077405c.zip
Reduce the number of files probed when finding a lisp file.
* src/lread.c (get-load-suffixes): Do not add any suffix to files that need to be loaded by the dynamic linker. (effective_load_path): Remove function. (load): Don't add any suffix if file ends in a suffix already. (effective_load_path): Remove function. (openp_add_middle_dir_to_suffixes): Add helper function to create pairs of middle directories and suffixes. (openp_max_middledir_and_suffix_len): Add helper function to count the number of bytes needed to store the middle directory and suffix. (openp_fill_filename_buffer): Add helper function to copy middle directory, basename and suffix to the filename buffer.
Diffstat (limited to 'src')
-rw-r--r--src/lread.c203
1 files changed, 154 insertions, 49 deletions
diff --git a/src/lread.c b/src/lread.c
index 192c7ba773a..a3e8d07c563 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1056,31 +1056,27 @@ This uses the variables `load-suffixes' and `load-file-rep-suffixes'. */)
1056 { 1056 {
1057 Lisp_Object exts = Vload_file_rep_suffixes; 1057 Lisp_Object exts = Vload_file_rep_suffixes;
1058 Lisp_Object suffix = XCAR (suffixes); 1058 Lisp_Object suffix = XCAR (suffixes);
1059 FOR_EACH_TAIL (exts) 1059 bool native_code_suffix =
1060 lst = Fcons (concat2 (suffix, XCAR (exts)), lst); 1060 NATIVE_COMP_FLAG
1061 } 1061 && strcmp (NATIVE_ELISP_SUFFIX, SSDATA (suffix)) == 0;
1062 return Fnreverse (lst);
1063}
1064 1062
1065static Lisp_Object 1063#ifdef HAVE_MODULES
1066effective_load_path (void) 1064 native_code_suffix =
1067{ 1065 native_code_suffix || strcmp (MODULES_SUFFIX, SSDATA (suffix)) == 0;
1068#ifndef HAVE_NATIVE_COMP 1066#ifdef MODULES_SECONDARY_SUFFIX
1069 return Vload_path; 1067 native_code_suffix =
1070#else 1068 native_code_suffix
1071 Lisp_Object lp = Vload_path; 1069 || strcmp (MODULES_SECONDARY_SUFFIX, SSDATA (suffix)) == 0;
1072 Lisp_Object new_lp = Qnil;
1073 FOR_EACH_TAIL (lp)
1074 {
1075 Lisp_Object el = XCAR (lp);
1076 new_lp =
1077 Fcons (concat2 (Ffile_name_as_directory (el),
1078 Vcomp_native_path_postfix),
1079 new_lp);
1080 new_lp = Fcons (el, new_lp);
1081 }
1082 return Fnreverse (new_lp);
1083#endif 1070#endif
1071#endif
1072
1073 if (native_code_suffix)
1074 lst = Fcons (suffix, lst);
1075 else
1076 FOR_EACH_TAIL (exts)
1077 lst = Fcons (concat2 (suffix, XCAR (exts)), lst);
1078 }
1079 return Fnreverse (lst);
1084} 1080}
1085 1081
1086/* Return true if STRING ends with SUFFIX. */ 1082/* Return true if STRING ends with SUFFIX. */
@@ -1218,7 +1214,7 @@ Return t if the file exists and loads successfully. */)
1218 || suffix_p (file, MODULES_SECONDARY_SUFFIX) 1214 || suffix_p (file, MODULES_SECONDARY_SUFFIX)
1219#endif 1215#endif
1220#endif 1216#endif
1221 ) 1217 || (NATIVE_COMP_FLAG && suffix_p (file, NATIVE_ELISP_SUFFIX)))
1222 must_suffix = Qnil; 1218 must_suffix = Qnil;
1223 /* Don't insist on adding a suffix 1219 /* Don't insist on adding a suffix
1224 if the argument includes a directory name. */ 1220 if the argument includes a directory name. */
@@ -1236,8 +1232,7 @@ Return t if the file exists and loads successfully. */)
1236 } 1232 }
1237 1233
1238 fd = 1234 fd =
1239 openp (effective_load_path (), file, suffixes, &found, Qnil, 1235 openp (Vload_path, file, suffixes, &found, Qnil, load_prefer_newer);
1240 load_prefer_newer);
1241 } 1236 }
1242 1237
1243 if (fd == -1) 1238 if (fd == -1)
@@ -1612,6 +1607,114 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */)
1612 return file; 1607 return file;
1613} 1608}
1614 1609
1610/* This function turns a list of suffixes into a list of middle dirs
1611 and suffixes. If the suffix is not NATIVE_ELISP_SUFFIX then its
1612 suffix is nil and it is added to the list as is. Instead, if it
1613 suffix is NATIVE_ELISP_SUFFIX then two elements are added to the
1614 list. The first one has middledir equal to nil and the second uses
1615 comp-native-path-postfix as middledir. This is because we'd like
1616 to search for dir/foo.eln before dir/middledir/foo.eln.
1617
1618For example, it turns this:
1619
1620(".eln" ".elc" ".elc.gz" ".el" ".el.gz")
1621
1622 into this:
1623
1624((nil . ".eln")
1625 (comp-native-path-postfix . ".eln")
1626 (nil . ".elc")
1627 (nil . ".elc.gz")
1628 (nil . ".el")
1629 (nil . ".el.gz"))
1630*/
1631static Lisp_Object
1632openp_add_middle_dir_to_suffixes (Lisp_Object suffixes)
1633{
1634 Lisp_Object tail = suffixes;
1635 Lisp_Object extended_suf = Qnil;
1636 FOR_EACH_TAIL_SAFE (tail)
1637 {
1638#ifdef HAVE_NATIVE_COMP
1639 CHECK_STRING_CAR (tail);
1640 char * suf = SSDATA (XCAR (tail));
1641 if (strcmp (NATIVE_ELISP_SUFFIX, suf) == 0)
1642 {
1643 CHECK_STRING (Vcomp_native_path_postfix);
1644 /* Here we add them in the opposite order so that nreverse
1645 corrects it. */
1646 extended_suf = Fcons (Fcons (Qnil, XCAR (tail)), extended_suf);
1647 extended_suf = Fcons (Fcons (Vcomp_native_path_postfix, XCAR (tail)),
1648 extended_suf);
1649 }
1650 else
1651#endif
1652 extended_suf = Fcons (Fcons (Qnil, XCAR (tail)), extended_suf);
1653 }
1654
1655 suffixes = Fnreverse (extended_suf);
1656 return suffixes;
1657}
1658
1659/* This function takes a list of middledirs and suffixes and returns
1660 the maximum buffer space that this part of the filename will
1661 need. */
1662static ptrdiff_t
1663openp_max_middledir_and_suffix_len (Lisp_Object middledir_and_suffixes)
1664{
1665 ptrdiff_t max_extra_len = 0;
1666 Lisp_Object tail = middledir_and_suffixes;
1667 FOR_EACH_TAIL_SAFE (tail)
1668 {
1669 Lisp_Object middledir_and_suffix = XCAR (tail);
1670 Lisp_Object middledir = XCAR (middledir_and_suffix);
1671 Lisp_Object suffix = XCDR (middledir_and_suffix);
1672 ptrdiff_t len = SBYTES (suffix);
1673 if (!NILP (middledir))
1674 len += 2 + SBYTES (middledir); /* Add two slashes. */
1675 max_extra_len = max (max_extra_len, len);
1676 }
1677 return max_extra_len;
1678}
1679
1680/* This function completes the FN buffer with the middledir,
1681 basenameme, and suffix. It takes the directory length in DIRNAME,
1682 but it requires that it has been copied already to the start of
1683 the buffer.
1684
1685 After this function the FN buffer will be (depending on middledir)
1686 dirname/middledir/basename.suffix
1687 or
1688 dirname/basename.suffix
1689*/
1690static ptrdiff_t
1691openp_fill_filename_buffer (char *fn, ptrdiff_t dirnamelen,
1692 Lisp_Object basenamewext,
1693 Lisp_Object middledir_and_suffix)
1694{
1695 Lisp_Object middledir = XCAR (middledir_and_suffix);
1696 Lisp_Object suffix = XCDR (middledir_and_suffix);
1697 ptrdiff_t basenamewext_len = SBYTES (basenamewext);
1698 ptrdiff_t fnlen, lsuffix = SBYTES (suffix);
1699 ptrdiff_t lmiddledir = 0;
1700 if (!NILP (middledir))
1701 {
1702 /* Add 1 for the slash. */
1703 lmiddledir = SBYTES (middledir) + 1;
1704 memcpy (fn + dirnamelen, SDATA (middledir),
1705 lmiddledir - 1);
1706 fn[dirnamelen + (lmiddledir - 1)] = '/';
1707 }
1708
1709 memcpy (fn + dirnamelen + lmiddledir, SDATA (basenamewext),
1710 basenamewext_len);
1711 /* Make complete filename by appending SUFFIX. */
1712 memcpy (fn + dirnamelen + lmiddledir + basenamewext_len,
1713 SDATA (suffix), lsuffix + 1);
1714 fnlen = dirnamelen + lmiddledir + basenamewext_len + lsuffix;
1715 return fnlen;
1716}
1717
1615/* Search for a file whose name is STR, looking in directories 1718/* Search for a file whose name is STR, looking in directories
1616 in the Lisp list PATH, and trying suffixes from SUFFIX. 1719 in the Lisp list PATH, and trying suffixes from SUFFIX.
1617 On success, return a file descriptor (or 1 or -2 as described below). 1720 On success, return a file descriptor (or 1 or -2 as described below).
@@ -1649,7 +1752,8 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1649 ptrdiff_t want_length; 1752 ptrdiff_t want_length;
1650 Lisp_Object filename; 1753 Lisp_Object filename;
1651 Lisp_Object string, tail, encoded_fn, save_string; 1754 Lisp_Object string, tail, encoded_fn, save_string;
1652 ptrdiff_t max_suffix_len = 0; 1755 Lisp_Object middledir_and_suffixes;
1756 ptrdiff_t max_extra_len = 0;
1653 int last_errno = ENOENT; 1757 int last_errno = ENOENT;
1654 int save_fd = -1; 1758 int save_fd = -1;
1655 USE_SAFE_ALLOCA; 1759 USE_SAFE_ALLOCA;
@@ -1660,13 +1764,9 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1660 1764
1661 CHECK_STRING (str); 1765 CHECK_STRING (str);
1662 1766
1663 tail = suffixes; 1767 middledir_and_suffixes = openp_add_middle_dir_to_suffixes (suffixes);
1664 FOR_EACH_TAIL_SAFE (tail) 1768
1665 { 1769 max_extra_len = openp_max_middledir_and_suffix_len (middledir_and_suffixes);
1666 CHECK_STRING_CAR (tail);
1667 max_suffix_len = max (max_suffix_len,
1668 SBYTES (XCAR (tail)));
1669 }
1670 1770
1671 string = filename = encoded_fn = save_string = Qnil; 1771 string = filename = encoded_fn = save_string = Qnil;
1672 1772
@@ -1683,7 +1783,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1683 executable. */ 1783 executable. */
1684 FOR_EACH_TAIL_SAFE (path) 1784 FOR_EACH_TAIL_SAFE (path)
1685 { 1785 {
1686 ptrdiff_t baselen, prefixlen; 1786 ptrdiff_t dirnamelen, prefixlen;
1687 1787
1688 if (EQ (path, just_use_str)) 1788 if (EQ (path, just_use_str))
1689 filename = str; 1789 filename = str;
@@ -1700,35 +1800,40 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
1700 continue; 1800 continue;
1701 } 1801 }
1702 1802
1803
1703 /* Calculate maximum length of any filename made from 1804 /* Calculate maximum length of any filename made from
1704 this path element/specified file name and any possible suffix. */ 1805 this path element/specified file name and any possible suffix. */
1705 want_length = max_suffix_len + SBYTES (filename); 1806 want_length = max_extra_len + SBYTES (filename);
1706 if (fn_size <= want_length) 1807 if (fn_size <= want_length)
1707 { 1808 {
1708 fn_size = 100 + want_length; 1809 fn_size = 100 + want_length;
1709 fn = SAFE_ALLOCA (fn_size); 1810 fn = SAFE_ALLOCA (fn_size);
1710 } 1811 }
1711 1812
1813 Lisp_Object dirnamewslash = Ffile_name_directory (filename);
1814 Lisp_Object basenamewext = Ffile_name_nondirectory (filename);
1815
1712 /* Copy FILENAME's data to FN but remove starting /: if any. */ 1816 /* Copy FILENAME's data to FN but remove starting /: if any. */
1713 prefixlen = ((SCHARS (filename) > 2 1817 prefixlen = ((SCHARS (dirnamewslash) > 2
1714 && SREF (filename, 0) == '/' 1818 && SREF (dirnamewslash, 0) == '/'
1715 && SREF (filename, 1) == ':') 1819 && SREF (dirnamewslash, 1) == ':')
1716 ? 2 : 0); 1820 ? 2 : 0);
1717 baselen = SBYTES (filename) - prefixlen; 1821 dirnamelen = SBYTES (dirnamewslash) - prefixlen;
1718 memcpy (fn, SDATA (filename) + prefixlen, baselen); 1822 memcpy (fn, SDATA (dirnamewslash) + prefixlen, dirnamelen);
1719 1823
1720 /* Loop over suffixes. */ 1824 /* Loop over middledir_and_suffixes. */
1721 AUTO_LIST1 (empty_string_only, empty_unibyte_string); 1825 AUTO_LIST1 (empty_string_only, Fcons (Qnil, empty_unibyte_string));
1722 tail = NILP (suffixes) ? empty_string_only : suffixes; 1826 tail = NILP (middledir_and_suffixes) ? empty_string_only
1827 : middledir_and_suffixes;
1723 FOR_EACH_TAIL_SAFE (tail) 1828 FOR_EACH_TAIL_SAFE (tail)
1724 { 1829 {
1725 Lisp_Object suffix = XCAR (tail); 1830 Lisp_Object middledir_and_suffix = XCAR (tail);
1726 ptrdiff_t fnlen, lsuffix = SBYTES (suffix); 1831 Lisp_Object suffix = XCDR (middledir_and_suffix);
1727 Lisp_Object handler; 1832 Lisp_Object handler;
1728 1833
1729 /* Make complete filename by appending SUFFIX. */ 1834 ptrdiff_t fnlen = openp_fill_filename_buffer (fn, dirnamelen,
1730 memcpy (fn + baselen, SDATA (suffix), lsuffix + 1); 1835 basenamewext,
1731 fnlen = baselen + lsuffix; 1836 middledir_and_suffix);
1732 1837
1733 /* Check that the file exists and is not a directory. */ 1838 /* Check that the file exists and is not a directory. */
1734 /* We used to only check for handlers on non-absolute file names: 1839 /* We used to only check for handlers on non-absolute file names: