unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Not using DOC for ELisp files
@ 2021-12-28  1:48 Stefan Monnier
  2021-12-28  2:25 ` Po Lu
                   ` (4 more replies)
  0 siblings, 5 replies; 31+ messages in thread
From: Stefan Monnier @ 2021-12-28  1:48 UTC (permalink / raw)
  To: emacs-devel

The patch below removes from the DOC file the docstrings coming from
ELisp files.

In numbers (in my tests), this reduces the size of DOC from about 3.2MB
to about 850kB, and increases the pdmp size by about 53kB or about 0.7%.

The benefits aren't great, obviously, but it does remove some warts in
the `lread.c` code (into which I bumped in the `scratch/fcr` branch,
which is why this comes up now).

I have a vague recollection that such a change was mentioned in some
bugreport-discussion some months ago but I can't remember where.

Comments?


        Stefan


diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c
index d17c28be90..4f4b135589 100644
--- a/lib-src/make-docfile.c
+++ b/lib-src/make-docfile.c
@@ -20,7 +20,7 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 
 
 /* The arguments given to this program are all the C and Lisp source files
- of GNU Emacs.  .elc and .el and .c files are allowed.
+ of GNU Emacs.  .c files are allowed.
  A .o file can also be specified; the .c file it was made from is used.
  This helps the makefile pass the correct list of files.
  Option -d DIR means change to DIR before looking for files.
@@ -62,13 +62,9 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    Similarly, msdos defines this as sys_chdir, but we're not linking with the
    file where that function is defined.  */
 #undef chdir
-#define IS_SLASH(c)  ((c) == '/' || (c) == '\\' || (c) == ':')
-#else  /* not DOS_NT */
-#define IS_SLASH(c)  ((c) == '/')
 #endif /* not DOS_NT */
 
 static void scan_file (char *filename);
-static void scan_lisp_file (const char *filename, const char *mode);
 static void scan_c_file (char *filename, const char *mode);
 static void scan_c_stream (FILE *infile);
 static void start_globals (void);
@@ -238,16 +234,9 @@ put_filename (char *filename)
 static void
 scan_file (char *filename)
 {
-  ptrdiff_t len = strlen (filename);
-
   if (!generate_globals)
     put_filename (filename);
-  if (len > 4 && !strcmp (filename + len - 4, ".elc"))
-    scan_lisp_file (filename, "rb");
-  else if (len > 3 && !strcmp (filename + len - 3, ".el"))
-    scan_lisp_file (filename, "r");
-  else
-    scan_c_file (filename, "r");
+  scan_c_file (filename, "r");
 }
 
 static void
@@ -1225,453 +1214,4 @@ scan_c_stream (FILE *infile)
     fatal ("read error");
 }
 \f
-/* Read a file of Lisp code, compiled or interpreted.
- Looks for
-  (defun NAME ARGS DOCSTRING ...)
-  (defmacro NAME ARGS DOCSTRING ...)
-  (defsubst NAME ARGS DOCSTRING ...)
-  (autoload (quote NAME) FILE DOCSTRING ...)
-  (defvar NAME VALUE DOCSTRING)
-  (defconst NAME VALUE DOCSTRING)
-  (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
-  (fset (quote NAME) #[... DOCSTRING ...])
-  (defalias (quote NAME) #[... DOCSTRING ...])
-  (custom-declare-variable (quote NAME) VALUE DOCSTRING ...)
- starting in column zero.
- (quote NAME) may appear as 'NAME as well.
-
- We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
- When we find that, we save it for the following defining-form,
- and we use that instead of reading a doc string within that defining-form.
-
- For defvar, defconst, and fset we skip to the docstring with a kludgy
- formatting convention: all docstrings must appear on the same line as the
- initial open-paren (the one in column zero) and must contain a backslash
- and a newline immediately after the initial double-quote.  No newlines
- must appear between the beginning of the form and the first double-quote.
- For defun, defmacro, and autoload, we know how to skip over the
- arglist, but the doc string must still have a backslash and newline
- immediately after the double quote.
- The only source files that must follow this convention are preloaded
- uncompiled ones like loaddefs.el; aside from that, it is always the .elc
- file that we should look at, and they are no problem because byte-compiler
- output follows this convention.
- The NAME and DOCSTRING are output.
- NAME is preceded by `F' for a function or `V' for a variable.
- An entry is output only if DOCSTRING has \ newline just after the opening ".
- */
-
-static void
-skip_white (FILE *infile)
-{
-  int c;
-  do
-    c = getc (infile);
-  while (c_isspace (c));
-
-  ungetc (c, infile);
-}
-
-static void
-read_lisp_symbol (FILE *infile, char *buffer)
-{
-  int c;
-  char *fillp = buffer;
-
-  skip_white (infile);
-  while (true)
-    {
-      c = getc (infile);
-      if (c == '\\')
-	{
-	  c = getc (infile);
-	  if (c < 0)
-	    return;
-	  *fillp++ = c;
-	}
-      else if (c_isspace (c) || c == '(' || c == ')' || c < 0)
-	{
-	  ungetc (c, infile);
-	  *fillp = 0;
-	  break;
-	}
-      else
-	*fillp++ = c;
-    }
-
-  if (! buffer[0])
-    fprintf (stderr, "## expected a symbol, got '%c'\n", c);
-
-  skip_white (infile);
-}
-
-static bool
-search_lisp_doc_at_eol (FILE *infile)
-{
-  int c = 0, c1 = 0, c2 = 0;
-
-  /* Skip until the end of line; remember two previous chars.  */
-  while (c != '\n' && c != '\r' && c != EOF)
-    {
-      c2 = c1;
-      c1 = c;
-      c = getc (infile);
-    }
-
-  /* If two previous characters were " and \,
-     this is a doc string.  Otherwise, there is none.  */
-  if (c2 != '"' || c1 != '\\')
-    {
-#ifdef DEBUG
-      fprintf (stderr, "## non-docstring found\n");
-#endif
-      ungetc (c, infile);
-      return false;
-    }
-  return true;
-}
-
-#define DEF_ELISP_FILE(fn)  { #fn, sizeof(#fn) - 1 }
-
-static void
-scan_lisp_file (const char *filename, const char *mode)
-{
-  FILE *infile;
-  int c;
-  char *saved_string = 0;
-  /* These are the only files that are loaded uncompiled, and must
-     follow the conventions of the doc strings expected by this
-     function.  These conventions are automatically followed by the
-     byte compiler when it produces the .elc files.  */
-  static struct {
-    const char *fn;
-    int fl;
-  } const uncompiled[] = {
-    DEF_ELISP_FILE (loaddefs.el),
-    DEF_ELISP_FILE (loadup.el),
-    DEF_ELISP_FILE (charprop.el),
-    DEF_ELISP_FILE (cp51932.el),
-    DEF_ELISP_FILE (eucjp-ms.el)
-  };
-  int i;
-  int flen = strlen (filename);
-
-  if (generate_globals)
-    fatal ("scanning lisp file when -g specified");
-  if (flen > 3 && !strcmp (filename + flen - 3, ".el"))
-    {
-      bool match = false;
-      for (i = 0; i < sizeof (uncompiled) / sizeof (uncompiled[0]); i++)
-	{
-	  if (uncompiled[i].fl <= flen
-	      && !strcmp (filename + flen - uncompiled[i].fl, uncompiled[i].fn)
-	      && (flen == uncompiled[i].fl
-		  || IS_SLASH (filename[flen - uncompiled[i].fl - 1])))
-	    {
-	      match = true;
-	      break;
-	    }
-	}
-      if (!match)
-	fatal ("uncompiled lisp file %s is not supported", filename);
-    }
-
-  infile = fopen (filename, mode);
-  if (infile == NULL)
-    {
-      perror (filename);
-      exit (EXIT_FAILURE);
-    }
-
-  c = '\n';
-  while (!feof (infile))
-    {
-      char buffer[BUFSIZ];
-      char type;
-
-      /* If not at end of line, skip till we get to one.  */
-      if (c != '\n' && c != '\r')
-	{
-	  c = getc (infile);
-	  continue;
-	}
-      /* Skip the line break.  */
-      while (c == '\n' || c == '\r')
-	c = getc (infile);
-      /* Detect a dynamic doc string and save it for the next expression.  */
-      if (c == '#')
-	{
-	  c = getc (infile);
-	  if (c == '@')
-	    {
-	      ptrdiff_t length = 0;
-	      ptrdiff_t i;
-
-	      /* Read the length.  */
-	      while ((c = getc (infile),
-		      c_isdigit (c)))
-		{
-		  if (INT_MULTIPLY_WRAPV (length, 10, &length)
-		      || INT_ADD_WRAPV (length, c - '0', &length)
-		      || SIZE_MAX < length)
-		    memory_exhausted ();
-		}
-
-	      if (length <= 1)
-		fatal ("invalid dynamic doc string length");
-
-	      if (c != ' ')
-		fatal ("space not found after dynamic doc string length");
-
-	      /* The next character is a space that is counted in the length
-		 but not part of the doc string.
-		 We already read it, so just ignore it.  */
-	      length--;
-
-	      /* Read in the contents.  */
-	      free (saved_string);
-	      saved_string = xmalloc (length);
-	      for (i = 0; i < length; i++)
-		saved_string[i] = getc (infile);
-	      /* The last character is a ^_.
-		 That is needed in the .elc file
-		 but it is redundant in DOC.  So get rid of it here.  */
-	      saved_string[length - 1] = 0;
-	      /* Skip the line break.  */
-	      while (c == '\n' || c == '\r')
-		c = getc (infile);
-	      /* Skip the following line.  */
-	      while (! (c == '\n' || c == '\r' || c < 0))
-		c = getc (infile);
-	    }
-	  continue;
-	}
-
-      if (c != '(')
-	continue;
-
-      read_lisp_symbol (infile, buffer);
-
-      if (! strcmp (buffer, "defun")
-	  || ! strcmp (buffer, "defmacro")
-	  || ! strcmp (buffer, "defsubst"))
-	{
-	  type = 'F';
-	  read_lisp_symbol (infile, buffer);
-
-	  /* Skip the arguments: either "nil" or a list in parens.  */
-
-	  c = getc (infile);
-	  if (c == 'n') /* nil */
-	    {
-	      if ((c = getc (infile)) != 'i'
-		  || (c = getc (infile)) != 'l')
-		{
-		  fprintf (stderr, "## unparsable arglist in %s (%s)\n",
-			   buffer, filename);
-		  continue;
-		}
-	    }
-	  else if (c != '(')
-	    {
-	      fprintf (stderr, "## unparsable arglist in %s (%s)\n",
-		       buffer, filename);
-	      continue;
-	    }
-	  else
-	    while (! (c == ')' || c < 0))
-	      c = getc (infile);
-	  skip_white (infile);
-
-	  /* If the next three characters aren't `dquote bslash newline'
-	     then we're not reading a docstring.
-	   */
-	  if ((c = getc (infile)) != '"'
-	      || (c = getc (infile)) != '\\'
-	      || ((c = getc (infile)) != '\n' && c != '\r'))
-	    {
-#ifdef DEBUG
-	      fprintf (stderr, "## non-docstring in %s (%s)\n",
-		       buffer, filename);
-#endif
-	      continue;
-	    }
-	}
-
-      /* defcustom can only occur in uncompiled Lisp files.  */
-      else if (! strcmp (buffer, "defvar")
-	       || ! strcmp (buffer, "defconst")
-	       || ! strcmp (buffer, "defcustom"))
-	{
-	  type = 'V';
-	  read_lisp_symbol (infile, buffer);
-
-	  if (saved_string == 0)
-	    if (!search_lisp_doc_at_eol (infile))
-	      continue;
-	}
-
-      else if (! strcmp (buffer, "custom-declare-variable")
-	       || ! strcmp (buffer, "defvaralias")
-	       )
-	{
-	  type = 'V';
-
-	  c = getc (infile);
-	  if (c == '\'')
-	    read_lisp_symbol (infile, buffer);
-	  else
-	    {
-	      if (c != '(')
-		{
-		  fprintf (stderr,
-			   "## unparsable name in custom-declare-variable in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      if (strcmp (buffer, "quote"))
-		{
-		  fprintf (stderr,
-			   "## unparsable name in custom-declare-variable in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      c = getc (infile);
-	      if (c != ')')
-		{
-		  fprintf (stderr,
-			   "## unparsable quoted name in custom-declare-variable in %s\n",
-			   filename);
-		  continue;
-		}
-	    }
-
-	  if (saved_string == 0)
-	    if (!search_lisp_doc_at_eol (infile))
-	      continue;
-	}
-
-      else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
-	{
-	  type = 'F';
-
-	  c = getc (infile);
-	  if (c == '\'')
-	    read_lisp_symbol (infile, buffer);
-	  else
-	    {
-	      if (c != '(')
-		{
-		  fprintf (stderr, "## unparsable name in fset in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      if (strcmp (buffer, "quote"))
-		{
-		  fprintf (stderr, "## unparsable name in fset in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      c = getc (infile);
-	      if (c != ')')
-		{
-		  fprintf (stderr,
-			   "## unparsable quoted name in fset in %s\n",
-			   filename);
-		  continue;
-		}
-	    }
-
-	  if (saved_string == 0)
-	    if (!search_lisp_doc_at_eol (infile))
-	      continue;
-	}
-
-      else if (! strcmp (buffer, "autoload"))
-	{
-	  type = 'F';
-	  c = getc (infile);
-	  if (c == '\'')
-	    read_lisp_symbol (infile, buffer);
-	  else
-	    {
-	      if (c != '(')
-		{
-		  fprintf (stderr, "## unparsable name in autoload in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      if (strcmp (buffer, "quote"))
-		{
-		  fprintf (stderr, "## unparsable name in autoload in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      c = getc (infile);
-	      if (c != ')')
-		{
-		  fprintf (stderr,
-			   "## unparsable quoted name in autoload in %s\n",
-			   filename);
-		  continue;
-		}
-	    }
-	  skip_white (infile);
-	  c = getc (infile);
-	  if (c != '\"')
-	    {
-	      fprintf (stderr, "## autoload of %s unparsable (%s)\n",
-		       buffer, filename);
-	      continue;
-	    }
-	  read_c_string_or_comment (infile, 0, false, 0);
-
-	  if (saved_string == 0)
-	    if (!search_lisp_doc_at_eol (infile))
-	      continue;
-	}
-
-#ifdef DEBUG
-      else if (! strcmp (buffer, "if")
-	       || ! strcmp (buffer, "byte-code"))
-	continue;
-#endif
-
-      else
-	{
-#ifdef DEBUG
-	  fprintf (stderr, "## unrecognized top-level form, %s (%s)\n",
-		   buffer, filename);
-#endif
-	  continue;
-	}
-
-      /* At this point, we should either use the previous dynamic doc string in
-	 saved_string or gobble a doc string from the input file.
-	 In the latter case, the opening quote (and leading backslash-newline)
-	 have already been read.  */
-
-      printf ("\037%c%s\n", type, buffer);
-      if (saved_string)
-	{
-	  fputs (saved_string, stdout);
-	  /* Don't use one dynamic doc string twice.  */
-	  free (saved_string);
-	  saved_string = 0;
-	}
-      else
-	read_c_string_or_comment (infile, 1, false, 0);
-    }
-  free (saved_string);
-  if (ferror (infile) || fclose (infile) != 0)
-    fatal ("%s: read error", filename);
-}
-
-
 /* make-docfile.c ends here */
diff --git a/lisp/startup.el b/lisp/startup.el
index b79467339b..727432a4cb 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -1056,6 +1056,9 @@ startup--load-user-init-file
     (when debug-on-error-should-be-set
       (setq debug-on-error debug-on-error-from-init-file))))
 
+(defvar lisp-directory nil
+  "Directory containing the Lisp files that come with GNU Emacs.")
+
 (defun command-line ()
   "A subroutine of `normal-top-level'.
 Amongst another things, it parses the command-line arguments."
@@ -1087,8 +1090,7 @@ command-line
   (let ((simple-file-name
 	 ;; Look for simple.el or simple.elc and use their directory
 	 ;; as the place where all Lisp files live.
-	 (locate-file "simple" load-path (get-load-suffixes)))
-	lisp-dir)
+	 (locate-file "simple" load-path (get-load-suffixes))))
     ;; Don't abort if simple.el cannot be found, but print a warning.
     ;; Although in most usage we are going to cryptically abort a moment
     ;; later anyway, due to missing required bidi data files (eg bug#13430).
@@ -1104,12 +1106,13 @@ command-line
 	  (unless (file-readable-p lispdir)
 	    (princ (format "Lisp directory %s not readable?" lispdir))
 	    (terpri)))
-      (setq lisp-dir (file-truename (file-name-directory simple-file-name)))
+      (setq lisp-directory
+            (file-truename (file-name-directory simple-file-name)))
       (setq load-history
 	    (mapcar (lambda (elt)
 		      (if (and (stringp (car elt))
 			       (not (file-name-absolute-p (car elt))))
-			  (cons (concat lisp-dir
+			  (cons (concat lisp-directory
 					(car elt))
 				(cdr elt))
 			elt))
diff --git a/src/Makefile.in b/src/Makefile.in
index ea4a7207ff..76e4675c2a 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -642,13 +642,11 @@ $(pdmp):
 ## for the first time, this prevents any variation between configurations
 ## in the contents of the DOC file.
 ##
-$(etc)/DOC: lisp.mk $(libsrc)/make-docfile$(EXEEXT) $(doc_obj) $(lisp)
+$(etc)/DOC: $(libsrc)/make-docfile$(EXEEXT) $(doc_obj)
 	$(AM_V_GEN)$(MKDIR_P) $(etc)
 	$(AM_V_at)rm -f $(etc)/DOC
 	$(AM_V_at)$(libsrc)/make-docfile -d $(srcdir) \
 	  $(SOME_MACHINE_OBJECTS) $(doc_obj) > $(etc)/DOC
-	$(AM_V_at)$(libsrc)/make-docfile -a $(etc)/DOC -d $(lispsource) \
-	  $(shortlisp)
 
 $(libsrc)/make-docfile$(EXEEXT) $(libsrc)/make-fingerprint$(EXEEXT): \
   $(lib)/libgnu.a
diff --git a/src/doc.c b/src/doc.c
index 6be023bb93..17601c700e 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -84,16 +84,19 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
   char *from, *to, *name, *p, *p1;
   Lisp_Object file, pos;
   ptrdiff_t count = SPECPDL_INDEX ();
+  Lisp_Object dir;
   USE_SAFE_ALLOCA;
 
   if (FIXNUMP (filepos))
     {
       file = Vdoc_file_name;
+      dir = Vdoc_directory;
       pos = filepos;
     }
   else if (CONSP (filepos))
     {
       file = XCAR (filepos);
+      dir = Fsymbol_value (intern ("lisp-directory"));
       pos = XCDR (filepos);
     }
   else
@@ -101,7 +104,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
 
   EMACS_INT position = eabs (XFIXNUM (pos));
 
-  if (!STRINGP (Vdoc_directory))
+  if (!STRINGP (dir))
     return Qnil;
 
   if (!STRINGP (file))
@@ -113,7 +116,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
   Lisp_Object tem = Ffile_name_absolute_p (file);
   file = ENCODE_FILE (file);
   Lisp_Object docdir
-    = NILP (tem) ? ENCODE_FILE (Vdoc_directory) : empty_unibyte_string;
+    = NILP (tem) ? ENCODE_FILE (dir) : empty_unibyte_string;
   ptrdiff_t docdir_sizemax = SBYTES (docdir) + 1;
   if (will_dump_p ())
     docdir_sizemax = max (docdir_sizemax, sizeof sibling_etc);
diff --git a/src/lread.c b/src/lread.c
index 4992576414..55b3d473dc 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1545,7 +1545,7 @@ Return t if the file exists and loads successfully.  */)
 	message_with_string ("Loading %s...", file, 1);
     }
 
-  specbind (Qload_file_name, found_eff);
+  specbind (Qload_file_name, hist_file_name);
   specbind (Qload_true_file_name, found);
   specbind (Qinhibit_file_name_operation, Qnil);
   specbind (Qload_in_progress, Qt);
@@ -3224,23 +3224,6 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
 		    Fstring_as_unibyte (AREF (tmp, COMPILED_BYTECODE)));
 	    }
 
-	  if (COMPILED_DOC_STRING < ASIZE (tmp)
-	      && EQ (AREF (tmp, COMPILED_DOC_STRING), make_fixnum (0)))
-	    {
-	      /* read_list found a docstring like '(#$ . 5521)' and treated it
-		 as 0.  This placeholder 0 would lead to accidental sharing in
-		 purecopy's hash-consing, so replace it with a (hopefully)
-		 unique integer placeholder, which is negative so that it is
-		 not confused with a DOC file offset (the USE_LSB_TAG shift
-		 relies on the fact that VALMASK is one bit narrower than
-		 INTMASK).  Eventually Snarf-documentation should replace the
-		 placeholder with the actual docstring.  */
-	      verify (INTMASK & ~VALMASK);
-	      EMACS_UINT hash = ((XHASH (tmp) >> USE_LSB_TAG)
-				 | (INTMASK - INTMASK / 2));
-	      ASET (tmp, COMPILED_DOC_STRING, make_ufixnum (hash));
-	    }
-
 	  XSETPVECTYPE (vec, PVEC_COMPILED);
 	  return tmp;
 	}
@@ -4208,31 +4191,13 @@ read_list (bool flag, Lisp_Object readcharfun)
 
       /* While building, if the list starts with #$, treat it specially.  */
       if (EQ (elt, Vload_file_name)
-	  && ! NILP (elt)
-	  && !NILP (Vpurify_flag))
+	  && ! NILP (elt))
 	{
-	  if (NILP (Vdoc_file_name))
-	    /* We have not yet called Snarf-documentation, so assume
-	       this file is described in the DOC file
-	       and Snarf-documentation will fill in the right value later.
-	       For now, replace the whole list with 0.  */
-	    doc_reference = 1;
-	  else
-	    /* We have already called Snarf-documentation, so make a relative
-	       file name for this file, so it can be found properly
-	       in the installed Lisp directory.
-	       We don't use Fexpand_file_name because that would make
-	       the directory absolute now.  */
-	    {
-	      AUTO_STRING (dot_dot_lisp, "../lisp/");
-	      elt = concat2 (dot_dot_lisp, Ffile_name_nondirectory (elt));
-	    }
+	  if (!NILP (Vpurify_flag))
+	    doc_reference = 0;
+	  else if (load_force_doc_strings)
+	    doc_reference = 2;
 	}
-      else if (EQ (elt, Vload_file_name)
-	       && ! NILP (elt)
-	       && load_force_doc_strings)
-	doc_reference = 2;
-
       if (ch)
 	{
 	  if (flag > 0)
@@ -4253,8 +4218,6 @@ read_list (bool flag, Lisp_Object readcharfun)
 
 	      if (ch == ')')
 		{
-		  if (doc_reference == 1)
-		    return make_fixnum (0);
 		  if (doc_reference == 2 && FIXNUMP (XCDR (val)))
 		    {
 		      char *saved = NULL;




^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28  1:48 Not using DOC for ELisp files Stefan Monnier
@ 2021-12-28  2:25 ` Po Lu
  2021-12-28  3:48   ` Stefan Kangas
                     ` (2 more replies)
  2021-12-28  3:39 ` Stefan Kangas
                   ` (3 subsequent siblings)
  4 siblings, 3 replies; 31+ messages in thread
From: Po Lu @ 2021-12-28  2:25 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> I have a vague recollection that such a change was mentioned in some
> bugreport-discussion some months ago but I can't remember where.
>
> Comments?

BTW, while we're removing things like this, how about getting rid of
pure space?  Is it really necessary in this millennium, even for the
unexec build?

That should work without pure space, right?

It would make the incremental garbage collector I'm slowly working
towards somewhat simpler.

Thanks.



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28  1:48 Not using DOC for ELisp files Stefan Monnier
  2021-12-28  2:25 ` Po Lu
@ 2021-12-28  3:39 ` Stefan Kangas
  2021-12-28  5:10   ` Stefan Monnier
  2021-12-28  6:56 ` Lars Ingebrigtsen
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 31+ messages in thread
From: Stefan Kangas @ 2021-12-28  3:39 UTC (permalink / raw)
  To: Stefan Monnier, emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> I have a vague recollection that such a change was mentioned in some
> bugreport-discussion some months ago but I can't remember where.

Bug#27748, maybe?

> Comments?

FWIW, I'm all for this simplification.

What about the comment about DOC in bytecomp.el?  Should that be removed
as well?



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28  2:25 ` Po Lu
@ 2021-12-28  3:48   ` Stefan Kangas
  2021-12-28  5:39     ` Po Lu
  2021-12-28  4:11   ` LdBeth
  2021-12-28  7:10   ` Lars Ingebrigtsen
  2 siblings, 1 reply; 31+ messages in thread
From: Stefan Kangas @ 2021-12-28  3:48 UTC (permalink / raw)
  To: Po Lu, Stefan Monnier; +Cc: emacs-devel

Po Lu <luangruo@yahoo.com> writes:

> BTW, while we're removing things like this, how about getting rid of
> pure space?  Is it really necessary in this millennium, even for the
> unexec build?

See Bug#36649.

> It would make the incremental garbage collector I'm slowly working
> towards somewhat simpler.

Cool!  An incremental GC would be great, to say the least.



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28  2:25 ` Po Lu
  2021-12-28  3:48   ` Stefan Kangas
@ 2021-12-28  4:11   ` LdBeth
  2021-12-28  5:03     ` Stefan Monnier
                       ` (2 more replies)
  2021-12-28  7:10   ` Lars Ingebrigtsen
  2 siblings, 3 replies; 31+ messages in thread
From: LdBeth @ 2021-12-28  4:11 UTC (permalink / raw)
  To: Po Lu; +Cc: Stefan Monnier, emacs-devel

>>>>> In <871r1xzcrl.fsf@yahoo.com> 
>>>>>	Po Lu <luangruo@yahoo.com> wrote:
Po> BTW, while we're removing things like this, how about getting rid
Po> of pure space?  Is it really necessary in this millennium, even
Po> for the unexec build?

Po> That should work without pure space, right?

Po> It would make the incremental garbage collector I'm slowly working
Po> towards somewhat simpler.

Having some data declared to be static can speed up GC scanning. It
does no longer really matter for sharing pure storage across different
emacs processes since today's emacsists get plenty of RAM IMO.
Probably that could be dropped in favor of a generational GC.

-- 
LDB



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28  4:11   ` LdBeth
@ 2021-12-28  5:03     ` Stefan Monnier
  2021-12-28  5:38     ` Po Lu
  2021-12-28  9:52     ` Phil Sainty
  2 siblings, 0 replies; 31+ messages in thread
From: Stefan Monnier @ 2021-12-28  5:03 UTC (permalink / raw)
  To: LdBeth; +Cc: Po Lu, emacs-devel

> Having some data declared to be static can speed up GC scanning.

But ever since the switch to pdumper, the purespace is not treated
specially any more (i.e. it's scanned along with the rest of the heap),
so we already lost this benefit.


        Stefan




^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28  3:39 ` Stefan Kangas
@ 2021-12-28  5:10   ` Stefan Monnier
  0 siblings, 0 replies; 31+ messages in thread
From: Stefan Monnier @ 2021-12-28  5:10 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: emacs-devel

>> I have a vague recollection that such a change was mentioned in some
>> bugreport-discussion some months ago but I can't remember where.
> Bug#27748, maybe?

That's the one, thanks.

> What about the comment about DOC in bytecomp.el?  Should that be removed
> as well?

Maybe not removed, but yes, I should adjust it accordingly.


        Stefan




^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28  4:11   ` LdBeth
  2021-12-28  5:03     ` Stefan Monnier
@ 2021-12-28  5:38     ` Po Lu
  2021-12-28  9:52     ` Phil Sainty
  2 siblings, 0 replies; 31+ messages in thread
From: Po Lu @ 2021-12-28  5:38 UTC (permalink / raw)
  To: LdBeth; +Cc: Stefan Monnier, emacs-devel

LdBeth <andpuke@foxmail.com> writes:

> Having some data declared to be static can speed up GC scanning.

I doubt it's significant.

> Probably that could be dropped in favor of a generational GC.

My opinion is that pure space constitutes a very primitive form of
generational garbage collection, where purified data is a permanant
"old" generation.

However, I doubt that gives any perceivable benefit to GC time today.



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28  3:48   ` Stefan Kangas
@ 2021-12-28  5:39     ` Po Lu
  0 siblings, 0 replies; 31+ messages in thread
From: Po Lu @ 2021-12-28  5:39 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: Stefan Monnier, emacs-devel

Stefan Kangas <stefankangas@gmail.com> writes:

> See Bug#36649.

Thanks.



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28  1:48 Not using DOC for ELisp files Stefan Monnier
  2021-12-28  2:25 ` Po Lu
  2021-12-28  3:39 ` Stefan Kangas
@ 2021-12-28  6:56 ` Lars Ingebrigtsen
  2021-12-28 12:44 ` Eli Zaretskii
  2022-01-03 13:48 ` Ken Raeburn
  4 siblings, 0 replies; 31+ messages in thread
From: Lars Ingebrigtsen @ 2021-12-28  6:56 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> The patch below removes from the DOC file the docstrings coming from
> ELisp files.

Makes sense to me.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28  2:25 ` Po Lu
  2021-12-28  3:48   ` Stefan Kangas
  2021-12-28  4:11   ` LdBeth
@ 2021-12-28  7:10   ` Lars Ingebrigtsen
  2 siblings, 0 replies; 31+ messages in thread
From: Lars Ingebrigtsen @ 2021-12-28  7:10 UTC (permalink / raw)
  To: Po Lu; +Cc: Stefan Monnier, emacs-devel

Po Lu <luangruo@yahoo.com> writes:

> BTW, while we're removing things like this, how about getting rid of
> pure space?  Is it really necessary in this millennium, even for the
> unexec build?

Yes, we should get rid of pure space.

> It would make the incremental garbage collector I'm slowly working
> towards somewhat simpler.

Wow, having incremental gc would be great.  😀

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28  4:11   ` LdBeth
  2021-12-28  5:03     ` Stefan Monnier
  2021-12-28  5:38     ` Po Lu
@ 2021-12-28  9:52     ` Phil Sainty
  2021-12-28 10:31       ` Po Lu
  2 siblings, 1 reply; 31+ messages in thread
From: Phil Sainty @ 2021-12-28  9:52 UTC (permalink / raw)
  To: LdBeth; +Cc: Po Lu, Stefan Monnier, emacs-devel

On 2021-12-28 17:11, LdBeth wrote:
> Probably that could be dropped in favor of a generational GC.

I believe that Jeff Walsh is currently continuing work on the
generational GC started by Daniel Colascione.

* https://lists.gnu.org/archive/html/emacs-devel/2021-06/msg00175.html
* https://github.com/fejfighter/emacs/commits/feature/newgc




^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28  9:52     ` Phil Sainty
@ 2021-12-28 10:31       ` Po Lu
  2021-12-28 12:47         ` Po Lu
  0 siblings, 1 reply; 31+ messages in thread
From: Po Lu @ 2021-12-28 10:31 UTC (permalink / raw)
  To: Phil Sainty; +Cc: LdBeth, Stefan Monnier, emacs-devel

Phil Sainty <psainty@orcon.net.nz> writes:

> I believe that Jeff Walsh is currently continuing work on the
> generational GC started by Daniel Colascione.

I don't think a purely generational GC is the way to go.  It's
inappropriate for an interactive program like Emacs, where
responsiveness is more important than raw GC performance.

Besides, the goal of my garbage collector is to be minimally invasive.

It extends the existing mark-and-sweep garbage collector to act
incrementally, and makes use of hardware write barriers.  (And as such
is unlikely to work on machines that don't support VM and something like
`mprotect'.)

It's still a work-in-progress with some features completely missing, and
it also has a lot of low-hanging optimization fruit.  For example, when
a write barrier is hit, the faulting address is looked up inside
mem_root, and the object found is simply pushed back onto the scan
stack.  (Nothing fancy is done with objects such as conses, where
chances are the object being written to it can be immediately marked
because it will not be modified further.)

Incremental marking already works in undumped Emacs, except for a tough
bug involving car-nested conses that are scanned from intervals on the
stack that cross a page, but I haven't worked on incremental sweeping
yet, and it doesn't work in a dumped Emacs at all.

Thanks.



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28  1:48 Not using DOC for ELisp files Stefan Monnier
                   ` (2 preceding siblings ...)
  2021-12-28  6:56 ` Lars Ingebrigtsen
@ 2021-12-28 12:44 ` Eli Zaretskii
  2021-12-28 17:14   ` Stefan Monnier
  2022-01-03 13:48 ` Ken Raeburn
  4 siblings, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2021-12-28 12:44 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Date: Mon, 27 Dec 2021 20:48:22 -0500
> 
> The patch below removes from the DOC file the docstrings coming from
> ELisp files.

What does this mean in terms of the run-time requirements in order to
get the doc strings for preloaded files?  Does it mean their *.elc
files should be available from the installation tree?  Or does it mean
the *.el files (which might be compressed) must be available?  And
what does this mean for a natively-compiled installation?

If there are any non-trivial consequences of this change, i.e. distros
will now need to make sure something happens that they didn't before,
I think we should get their opinions before we install this.

Thanks.



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28 10:31       ` Po Lu
@ 2021-12-28 12:47         ` Po Lu
  0 siblings, 0 replies; 31+ messages in thread
From: Po Lu @ 2021-12-28 12:47 UTC (permalink / raw)
  To: Phil Sainty; +Cc: LdBeth, Stefan Monnier, emacs-devel

Po Lu <luangruo@yahoo.com> writes:

> Incremental marking already works in undumped Emacs, except for a tough
> bug involving car-nested conses that are scanned from intervals on the
                                                                  ^^

Sorry for the typo, this should have been "reachable from".



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28 12:44 ` Eli Zaretskii
@ 2021-12-28 17:14   ` Stefan Monnier
  2021-12-28 18:17     ` Eli Zaretskii
  0 siblings, 1 reply; 31+ messages in thread
From: Stefan Monnier @ 2021-12-28 17:14 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

>> The patch below removes from the DOC file the docstrings coming from
>> ELisp files.
> What does this mean in terms of the run-time requirements in order to
> get the doc strings for preloaded files?  Does it mean their *.elc
> files should be available from the installation tree?

Yes, it means the docstring are fetched from the likes of
`lisp/files.elc` (as is already the case for the non-preloaded files)
instead of from `etc/DOC`.

> Or does it mean the *.el files (which might be compressed) must
> be available?

No, the `.el` files are not used any more than before.

> And what does this mean for a natively-compiled installation?

I don't think this has any impact.

> If there are any non-trivial consequences of this change, i.e. distros
> will now need to make sure something happens that they didn't before,
> I think we should get their opinions before we install this.

The only non-trivial consequence I can think of is when the compiled
preloaded files are missing.  E.g. if the distros remove
`lisp/files.elc`.  I don't aware of any distro/packaging doing it (even
tho it did make sense doing so to save a few bytes).


        Stefan




^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28 17:14   ` Stefan Monnier
@ 2021-12-28 18:17     ` Eli Zaretskii
  2021-12-29  0:15       ` Stefan Monnier
  0 siblings, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2021-12-28 18:17 UTC (permalink / raw)
  To: Stefan Monnier, Andrea Corallo; +Cc: emacs-devel

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: emacs-devel@gnu.org
> Date: Tue, 28 Dec 2021 12:14:43 -0500
> 
> Yes, it means the docstring are fetched from the likes of
> `lisp/files.elc` (as is already the case for the non-preloaded files)
> instead of from `etc/DOC`.
> 
> > Or does it mean the *.el files (which might be compressed) must
> > be available?
> 
> No, the `.el` files are not used any more than before.
> 
> > And what does this mean for a natively-compiled installation?
> 
> I don't think this has any impact.

So natively-compiled installations still need to make the *.elc files
available in the installation tree?

Andrea, is that a requirement regardless of the doc strings?  That is,
can one remove the *.elc files of the preloaded Lisp files once Emacs
is installed and the preloaded *.eln files are available?

> > If there are any non-trivial consequences of this change, i.e. distros
> > will now need to make sure something happens that they didn't before,
> > I think we should get their opinions before we install this.
> 
> The only non-trivial consequence I can think of is when the compiled
> preloaded files are missing.  E.g. if the distros remove
> `lisp/files.elc`.  I don't aware of any distro/packaging doing it (even
> tho it did make sense doing so to save a few bytes).

Well, I hope those of them who read this list will chime in if this is
of any concern.

Thanks.



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28 18:17     ` Eli Zaretskii
@ 2021-12-29  0:15       ` Stefan Monnier
  2021-12-29 12:30         ` Johann Klähn
  2021-12-29 12:52         ` Eli Zaretskii
  0 siblings, 2 replies; 31+ messages in thread
From: Stefan Monnier @ 2021-12-29  0:15 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Andrea Corallo, emacs-devel

Seeing how I haven't heard any opposition to the idea, I fixed a few
loose ends, and I think it's now ready.  See below.
Any objection?


        Stefan


2021-12-28  Stefan Monnier  <monnier@iro.umontreal.ca>

    * src/lread.c (Fload): Use relative file names for `load-file-name`
    when preloading for the dump, like we already did for `current-load-list`.
    (read_list): Don't zero-out dynamic docstring references during the
    preload since they won't be filled later by Snarf-documentation any more.
    (read1): Remove the hash-hack for doc references that were zeroed.

    * lisp/startup.el (lisp-directory): New variable.
    (command-line): Set it.

    * src/doc.c (get_doc_string): Use `lisp-directory` for dynamic
    docstring references using relative file names.
    (syms_of_doc): Add `Qlisp_directory`.

    * src/Makefile.in ($(etc)/DOC): Don't scan Lisp files any more.

    * lib-src/make-docfile.c (scan_file): Don't handle `.el` or `.elc`
    files any more.
    (IS_SLASH): Remove macro, not used any more.
    (skip_white, read_lisp_symbol, search_lisp_doc_at_eol)
    (scan_lisp_file): Remove functions, not used any more.

    * doc/lispref/loading.texi (Library Search): Mention `lisp-directory`.


diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi
index e4cd940ab2..e6a7d77ac9 100644
--- a/doc/lispref/loading.texi
+++ b/doc/lispref/loading.texi
@@ -292,13 +292,16 @@ Library Search
 @end defvar
 
   When Emacs starts up, it sets up the value of @code{load-path}
-in several steps.  First, it initializes @code{load-path} using
-default locations set when Emacs was compiled.  Normally, this
-is a directory something like
+in several steps.  First, it initializes @code{lisp-directory} using
+default locations set when Emacs was compiled.
 
+@defvar lisp-directory
+Name of the directory holding Emacs's bundled Lisp files.
+Normally, this is a directory something like
 @example
 "/usr/local/share/emacs/@var{version}/lisp"
 @end example
+@end defvar
 
 (In this and the following examples, replace @file{/usr/local} with
 the installation prefix appropriate for your Emacs.)
diff --git a/etc/NEWS b/etc/NEWS
index 96e95967ef..3363ce0371 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -883,6 +883,9 @@ The input must be encoded text.
 \f
 * Lisp Changes in Emacs 29.1
 
++++
+** New variable 'lisp-directory' holds the directory of Emacs's own Lisp files.
+
 +++
 ** New facility for handling session state: 'multisession-value'.
 This can be used as a convenient way to store (simple) application
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c
index d17c28be90..4f4b135589 100644
--- a/lib-src/make-docfile.c
+++ b/lib-src/make-docfile.c
@@ -20,7 +20,7 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 
 
 /* The arguments given to this program are all the C and Lisp source files
- of GNU Emacs.  .elc and .el and .c files are allowed.
+ of GNU Emacs.  .c files are allowed.
  A .o file can also be specified; the .c file it was made from is used.
  This helps the makefile pass the correct list of files.
  Option -d DIR means change to DIR before looking for files.
@@ -62,13 +62,9 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    Similarly, msdos defines this as sys_chdir, but we're not linking with the
    file where that function is defined.  */
 #undef chdir
-#define IS_SLASH(c)  ((c) == '/' || (c) == '\\' || (c) == ':')
-#else  /* not DOS_NT */
-#define IS_SLASH(c)  ((c) == '/')
 #endif /* not DOS_NT */
 
 static void scan_file (char *filename);
-static void scan_lisp_file (const char *filename, const char *mode);
 static void scan_c_file (char *filename, const char *mode);
 static void scan_c_stream (FILE *infile);
 static void start_globals (void);
@@ -238,16 +234,9 @@ put_filename (char *filename)
 static void
 scan_file (char *filename)
 {
-  ptrdiff_t len = strlen (filename);
-
   if (!generate_globals)
     put_filename (filename);
-  if (len > 4 && !strcmp (filename + len - 4, ".elc"))
-    scan_lisp_file (filename, "rb");
-  else if (len > 3 && !strcmp (filename + len - 3, ".el"))
-    scan_lisp_file (filename, "r");
-  else
-    scan_c_file (filename, "r");
+  scan_c_file (filename, "r");
 }
 
 static void
@@ -1225,453 +1214,4 @@ scan_c_stream (FILE *infile)
     fatal ("read error");
 }
 \f
-/* Read a file of Lisp code, compiled or interpreted.
- Looks for
-  (defun NAME ARGS DOCSTRING ...)
-  (defmacro NAME ARGS DOCSTRING ...)
-  (defsubst NAME ARGS DOCSTRING ...)
-  (autoload (quote NAME) FILE DOCSTRING ...)
-  (defvar NAME VALUE DOCSTRING)
-  (defconst NAME VALUE DOCSTRING)
-  (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
-  (fset (quote NAME) #[... DOCSTRING ...])
-  (defalias (quote NAME) #[... DOCSTRING ...])
-  (custom-declare-variable (quote NAME) VALUE DOCSTRING ...)
- starting in column zero.
- (quote NAME) may appear as 'NAME as well.
-
- We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
- When we find that, we save it for the following defining-form,
- and we use that instead of reading a doc string within that defining-form.
-
- For defvar, defconst, and fset we skip to the docstring with a kludgy
- formatting convention: all docstrings must appear on the same line as the
- initial open-paren (the one in column zero) and must contain a backslash
- and a newline immediately after the initial double-quote.  No newlines
- must appear between the beginning of the form and the first double-quote.
- For defun, defmacro, and autoload, we know how to skip over the
- arglist, but the doc string must still have a backslash and newline
- immediately after the double quote.
- The only source files that must follow this convention are preloaded
- uncompiled ones like loaddefs.el; aside from that, it is always the .elc
- file that we should look at, and they are no problem because byte-compiler
- output follows this convention.
- The NAME and DOCSTRING are output.
- NAME is preceded by `F' for a function or `V' for a variable.
- An entry is output only if DOCSTRING has \ newline just after the opening ".
- */
-
-static void
-skip_white (FILE *infile)
-{
-  int c;
-  do
-    c = getc (infile);
-  while (c_isspace (c));
-
-  ungetc (c, infile);
-}
-
-static void
-read_lisp_symbol (FILE *infile, char *buffer)
-{
-  int c;
-  char *fillp = buffer;
-
-  skip_white (infile);
-  while (true)
-    {
-      c = getc (infile);
-      if (c == '\\')
-	{
-	  c = getc (infile);
-	  if (c < 0)
-	    return;
-	  *fillp++ = c;
-	}
-      else if (c_isspace (c) || c == '(' || c == ')' || c < 0)
-	{
-	  ungetc (c, infile);
-	  *fillp = 0;
-	  break;
-	}
-      else
-	*fillp++ = c;
-    }
-
-  if (! buffer[0])
-    fprintf (stderr, "## expected a symbol, got '%c'\n", c);
-
-  skip_white (infile);
-}
-
-static bool
-search_lisp_doc_at_eol (FILE *infile)
-{
-  int c = 0, c1 = 0, c2 = 0;
-
-  /* Skip until the end of line; remember two previous chars.  */
-  while (c != '\n' && c != '\r' && c != EOF)
-    {
-      c2 = c1;
-      c1 = c;
-      c = getc (infile);
-    }
-
-  /* If two previous characters were " and \,
-     this is a doc string.  Otherwise, there is none.  */
-  if (c2 != '"' || c1 != '\\')
-    {
-#ifdef DEBUG
-      fprintf (stderr, "## non-docstring found\n");
-#endif
-      ungetc (c, infile);
-      return false;
-    }
-  return true;
-}
-
-#define DEF_ELISP_FILE(fn)  { #fn, sizeof(#fn) - 1 }
-
-static void
-scan_lisp_file (const char *filename, const char *mode)
-{
-  FILE *infile;
-  int c;
-  char *saved_string = 0;
-  /* These are the only files that are loaded uncompiled, and must
-     follow the conventions of the doc strings expected by this
-     function.  These conventions are automatically followed by the
-     byte compiler when it produces the .elc files.  */
-  static struct {
-    const char *fn;
-    int fl;
-  } const uncompiled[] = {
-    DEF_ELISP_FILE (loaddefs.el),
-    DEF_ELISP_FILE (loadup.el),
-    DEF_ELISP_FILE (charprop.el),
-    DEF_ELISP_FILE (cp51932.el),
-    DEF_ELISP_FILE (eucjp-ms.el)
-  };
-  int i;
-  int flen = strlen (filename);
-
-  if (generate_globals)
-    fatal ("scanning lisp file when -g specified");
-  if (flen > 3 && !strcmp (filename + flen - 3, ".el"))
-    {
-      bool match = false;
-      for (i = 0; i < sizeof (uncompiled) / sizeof (uncompiled[0]); i++)
-	{
-	  if (uncompiled[i].fl <= flen
-	      && !strcmp (filename + flen - uncompiled[i].fl, uncompiled[i].fn)
-	      && (flen == uncompiled[i].fl
-		  || IS_SLASH (filename[flen - uncompiled[i].fl - 1])))
-	    {
-	      match = true;
-	      break;
-	    }
-	}
-      if (!match)
-	fatal ("uncompiled lisp file %s is not supported", filename);
-    }
-
-  infile = fopen (filename, mode);
-  if (infile == NULL)
-    {
-      perror (filename);
-      exit (EXIT_FAILURE);
-    }
-
-  c = '\n';
-  while (!feof (infile))
-    {
-      char buffer[BUFSIZ];
-      char type;
-
-      /* If not at end of line, skip till we get to one.  */
-      if (c != '\n' && c != '\r')
-	{
-	  c = getc (infile);
-	  continue;
-	}
-      /* Skip the line break.  */
-      while (c == '\n' || c == '\r')
-	c = getc (infile);
-      /* Detect a dynamic doc string and save it for the next expression.  */
-      if (c == '#')
-	{
-	  c = getc (infile);
-	  if (c == '@')
-	    {
-	      ptrdiff_t length = 0;
-	      ptrdiff_t i;
-
-	      /* Read the length.  */
-	      while ((c = getc (infile),
-		      c_isdigit (c)))
-		{
-		  if (INT_MULTIPLY_WRAPV (length, 10, &length)
-		      || INT_ADD_WRAPV (length, c - '0', &length)
-		      || SIZE_MAX < length)
-		    memory_exhausted ();
-		}
-
-	      if (length <= 1)
-		fatal ("invalid dynamic doc string length");
-
-	      if (c != ' ')
-		fatal ("space not found after dynamic doc string length");
-
-	      /* The next character is a space that is counted in the length
-		 but not part of the doc string.
-		 We already read it, so just ignore it.  */
-	      length--;
-
-	      /* Read in the contents.  */
-	      free (saved_string);
-	      saved_string = xmalloc (length);
-	      for (i = 0; i < length; i++)
-		saved_string[i] = getc (infile);
-	      /* The last character is a ^_.
-		 That is needed in the .elc file
-		 but it is redundant in DOC.  So get rid of it here.  */
-	      saved_string[length - 1] = 0;
-	      /* Skip the line break.  */
-	      while (c == '\n' || c == '\r')
-		c = getc (infile);
-	      /* Skip the following line.  */
-	      while (! (c == '\n' || c == '\r' || c < 0))
-		c = getc (infile);
-	    }
-	  continue;
-	}
-
-      if (c != '(')
-	continue;
-
-      read_lisp_symbol (infile, buffer);
-
-      if (! strcmp (buffer, "defun")
-	  || ! strcmp (buffer, "defmacro")
-	  || ! strcmp (buffer, "defsubst"))
-	{
-	  type = 'F';
-	  read_lisp_symbol (infile, buffer);
-
-	  /* Skip the arguments: either "nil" or a list in parens.  */
-
-	  c = getc (infile);
-	  if (c == 'n') /* nil */
-	    {
-	      if ((c = getc (infile)) != 'i'
-		  || (c = getc (infile)) != 'l')
-		{
-		  fprintf (stderr, "## unparsable arglist in %s (%s)\n",
-			   buffer, filename);
-		  continue;
-		}
-	    }
-	  else if (c != '(')
-	    {
-	      fprintf (stderr, "## unparsable arglist in %s (%s)\n",
-		       buffer, filename);
-	      continue;
-	    }
-	  else
-	    while (! (c == ')' || c < 0))
-	      c = getc (infile);
-	  skip_white (infile);
-
-	  /* If the next three characters aren't `dquote bslash newline'
-	     then we're not reading a docstring.
-	   */
-	  if ((c = getc (infile)) != '"'
-	      || (c = getc (infile)) != '\\'
-	      || ((c = getc (infile)) != '\n' && c != '\r'))
-	    {
-#ifdef DEBUG
-	      fprintf (stderr, "## non-docstring in %s (%s)\n",
-		       buffer, filename);
-#endif
-	      continue;
-	    }
-	}
-
-      /* defcustom can only occur in uncompiled Lisp files.  */
-      else if (! strcmp (buffer, "defvar")
-	       || ! strcmp (buffer, "defconst")
-	       || ! strcmp (buffer, "defcustom"))
-	{
-	  type = 'V';
-	  read_lisp_symbol (infile, buffer);
-
-	  if (saved_string == 0)
-	    if (!search_lisp_doc_at_eol (infile))
-	      continue;
-	}
-
-      else if (! strcmp (buffer, "custom-declare-variable")
-	       || ! strcmp (buffer, "defvaralias")
-	       )
-	{
-	  type = 'V';
-
-	  c = getc (infile);
-	  if (c == '\'')
-	    read_lisp_symbol (infile, buffer);
-	  else
-	    {
-	      if (c != '(')
-		{
-		  fprintf (stderr,
-			   "## unparsable name in custom-declare-variable in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      if (strcmp (buffer, "quote"))
-		{
-		  fprintf (stderr,
-			   "## unparsable name in custom-declare-variable in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      c = getc (infile);
-	      if (c != ')')
-		{
-		  fprintf (stderr,
-			   "## unparsable quoted name in custom-declare-variable in %s\n",
-			   filename);
-		  continue;
-		}
-	    }
-
-	  if (saved_string == 0)
-	    if (!search_lisp_doc_at_eol (infile))
-	      continue;
-	}
-
-      else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
-	{
-	  type = 'F';
-
-	  c = getc (infile);
-	  if (c == '\'')
-	    read_lisp_symbol (infile, buffer);
-	  else
-	    {
-	      if (c != '(')
-		{
-		  fprintf (stderr, "## unparsable name in fset in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      if (strcmp (buffer, "quote"))
-		{
-		  fprintf (stderr, "## unparsable name in fset in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      c = getc (infile);
-	      if (c != ')')
-		{
-		  fprintf (stderr,
-			   "## unparsable quoted name in fset in %s\n",
-			   filename);
-		  continue;
-		}
-	    }
-
-	  if (saved_string == 0)
-	    if (!search_lisp_doc_at_eol (infile))
-	      continue;
-	}
-
-      else if (! strcmp (buffer, "autoload"))
-	{
-	  type = 'F';
-	  c = getc (infile);
-	  if (c == '\'')
-	    read_lisp_symbol (infile, buffer);
-	  else
-	    {
-	      if (c != '(')
-		{
-		  fprintf (stderr, "## unparsable name in autoload in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      if (strcmp (buffer, "quote"))
-		{
-		  fprintf (stderr, "## unparsable name in autoload in %s\n",
-			   filename);
-		  continue;
-		}
-	      read_lisp_symbol (infile, buffer);
-	      c = getc (infile);
-	      if (c != ')')
-		{
-		  fprintf (stderr,
-			   "## unparsable quoted name in autoload in %s\n",
-			   filename);
-		  continue;
-		}
-	    }
-	  skip_white (infile);
-	  c = getc (infile);
-	  if (c != '\"')
-	    {
-	      fprintf (stderr, "## autoload of %s unparsable (%s)\n",
-		       buffer, filename);
-	      continue;
-	    }
-	  read_c_string_or_comment (infile, 0, false, 0);
-
-	  if (saved_string == 0)
-	    if (!search_lisp_doc_at_eol (infile))
-	      continue;
-	}
-
-#ifdef DEBUG
-      else if (! strcmp (buffer, "if")
-	       || ! strcmp (buffer, "byte-code"))
-	continue;
-#endif
-
-      else
-	{
-#ifdef DEBUG
-	  fprintf (stderr, "## unrecognized top-level form, %s (%s)\n",
-		   buffer, filename);
-#endif
-	  continue;
-	}
-
-      /* At this point, we should either use the previous dynamic doc string in
-	 saved_string or gobble a doc string from the input file.
-	 In the latter case, the opening quote (and leading backslash-newline)
-	 have already been read.  */
-
-      printf ("\037%c%s\n", type, buffer);
-      if (saved_string)
-	{
-	  fputs (saved_string, stdout);
-	  /* Don't use one dynamic doc string twice.  */
-	  free (saved_string);
-	  saved_string = 0;
-	}
-      else
-	read_c_string_or_comment (infile, 1, false, 0);
-    }
-  free (saved_string);
-  if (ferror (infile) || fclose (infile) != 0)
-    fatal ("%s: read error", filename);
-}
-
-
 /* make-docfile.c ends here */
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 11107ec0f6..a64af022d4 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -4926,13 +4926,13 @@ byte-compile-file-form-defalias
   ;; if it weren't for the fact that we need to figure out when a defalias
   ;; defines a macro, so as to add it to byte-compile-macro-environment.
   ;;
-  ;; FIXME: we also use this hunk-handler to implement the function's dynamic
-  ;; docstring feature.  We could actually implement it more elegantly in
-  ;; byte-compile-lambda so it applies to all lambdas, but the problem is that
-  ;; the resulting .elc format will not be recognized by make-docfile, so
-  ;; either we stop using DOC for the docstrings of preloaded elc files (at the
-  ;; cost of around 24KB on 32bit hosts, double on 64bit hosts) or we need to
-  ;; build DOC in a more clever way (e.g. handle anonymous elements).
+  ;; FIXME: we also use this hunk-handler to implement the function's
+  ;; dynamic docstring feature (via byte-compile-file-form-defmumble).
+  ;; We should actually implement it (more elegantly) in
+  ;; byte-compile-lambda so it applies to all lambdas.  We did it here
+  ;; so the resulting .elc format was recognizable by make-docfile,
+  ;; but since then we stopped using DOC for the docstrings of
+  ;; preloaded elc files so that obstacle is gone.
   (let ((byte-compile-free-references nil)
         (byte-compile-free-assignments nil))
     (pcase form
diff --git a/lisp/startup.el b/lisp/startup.el
index b79467339b..727432a4cb 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -1056,6 +1056,9 @@ startup--load-user-init-file
     (when debug-on-error-should-be-set
       (setq debug-on-error debug-on-error-from-init-file))))
 
+(defvar lisp-directory nil
+  "Directory containing the Lisp files that come with GNU Emacs.")
+
 (defun command-line ()
   "A subroutine of `normal-top-level'.
 Amongst another things, it parses the command-line arguments."
@@ -1087,8 +1090,7 @@ command-line
   (let ((simple-file-name
 	 ;; Look for simple.el or simple.elc and use their directory
 	 ;; as the place where all Lisp files live.
-	 (locate-file "simple" load-path (get-load-suffixes)))
-	lisp-dir)
+	 (locate-file "simple" load-path (get-load-suffixes))))
     ;; Don't abort if simple.el cannot be found, but print a warning.
     ;; Although in most usage we are going to cryptically abort a moment
     ;; later anyway, due to missing required bidi data files (eg bug#13430).
@@ -1104,12 +1106,13 @@ command-line
 	  (unless (file-readable-p lispdir)
 	    (princ (format "Lisp directory %s not readable?" lispdir))
 	    (terpri)))
-      (setq lisp-dir (file-truename (file-name-directory simple-file-name)))
+      (setq lisp-directory
+            (file-truename (file-name-directory simple-file-name)))
       (setq load-history
 	    (mapcar (lambda (elt)
 		      (if (and (stringp (car elt))
 			       (not (file-name-absolute-p (car elt))))
-			  (cons (concat lisp-dir
+			  (cons (concat lisp-directory
 					(car elt))
 				(cdr elt))
 			elt))
diff --git a/src/Makefile.in b/src/Makefile.in
index ea4a7207ff..76e4675c2a 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -642,13 +642,11 @@ $(pdmp):
 ## for the first time, this prevents any variation between configurations
 ## in the contents of the DOC file.
 ##
-$(etc)/DOC: lisp.mk $(libsrc)/make-docfile$(EXEEXT) $(doc_obj) $(lisp)
+$(etc)/DOC: $(libsrc)/make-docfile$(EXEEXT) $(doc_obj)
 	$(AM_V_GEN)$(MKDIR_P) $(etc)
 	$(AM_V_at)rm -f $(etc)/DOC
 	$(AM_V_at)$(libsrc)/make-docfile -d $(srcdir) \
 	  $(SOME_MACHINE_OBJECTS) $(doc_obj) > $(etc)/DOC
-	$(AM_V_at)$(libsrc)/make-docfile -a $(etc)/DOC -d $(lispsource) \
-	  $(shortlisp)
 
 $(libsrc)/make-docfile$(EXEEXT) $(libsrc)/make-fingerprint$(EXEEXT): \
   $(lib)/libgnu.a
diff --git a/src/doc.c b/src/doc.c
index 6be023bb93..129d3a517b 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -84,16 +84,19 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
   char *from, *to, *name, *p, *p1;
   Lisp_Object file, pos;
   ptrdiff_t count = SPECPDL_INDEX ();
+  Lisp_Object dir;
   USE_SAFE_ALLOCA;
 
   if (FIXNUMP (filepos))
     {
       file = Vdoc_file_name;
+      dir = Vdoc_directory;
       pos = filepos;
     }
   else if (CONSP (filepos))
     {
       file = XCAR (filepos);
+      dir = Fsymbol_value (Qlisp_directory);
       pos = XCDR (filepos);
     }
   else
@@ -101,7 +104,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
 
   EMACS_INT position = eabs (XFIXNUM (pos));
 
-  if (!STRINGP (Vdoc_directory))
+  if (!STRINGP (dir))
     return Qnil;
 
   if (!STRINGP (file))
@@ -113,7 +116,7 @@ get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
   Lisp_Object tem = Ffile_name_absolute_p (file);
   file = ENCODE_FILE (file);
   Lisp_Object docdir
-    = NILP (tem) ? ENCODE_FILE (Vdoc_directory) : empty_unibyte_string;
+    = NILP (tem) ? ENCODE_FILE (dir) : empty_unibyte_string;
   ptrdiff_t docdir_sizemax = SBYTES (docdir) + 1;
   if (will_dump_p ())
     docdir_sizemax = max (docdir_sizemax, sizeof sibling_etc);
@@ -703,6 +706,7 @@ See variable `text-quoting-style'.  */)
 void
 syms_of_doc (void)
 {
+  DEFSYM (Qlisp_directory, "lisp-directory");
   DEFSYM (Qsubstitute_command_keys, "substitute-command-keys");
   DEFSYM (Qfunction_documentation, "function-documentation");
   DEFSYM (Qgrave, "grave");
diff --git a/src/lread.c b/src/lread.c
index 4992576414..55b3d473dc 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1545,7 +1545,7 @@ Return t if the file exists and loads successfully.  */)
 	message_with_string ("Loading %s...", file, 1);
     }
 
-  specbind (Qload_file_name, found_eff);
+  specbind (Qload_file_name, hist_file_name);
   specbind (Qload_true_file_name, found);
   specbind (Qinhibit_file_name_operation, Qnil);
   specbind (Qload_in_progress, Qt);
@@ -3224,23 +3224,6 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
 		    Fstring_as_unibyte (AREF (tmp, COMPILED_BYTECODE)));
 	    }
 
-	  if (COMPILED_DOC_STRING < ASIZE (tmp)
-	      && EQ (AREF (tmp, COMPILED_DOC_STRING), make_fixnum (0)))
-	    {
-	      /* read_list found a docstring like '(#$ . 5521)' and treated it
-		 as 0.  This placeholder 0 would lead to accidental sharing in
-		 purecopy's hash-consing, so replace it with a (hopefully)
-		 unique integer placeholder, which is negative so that it is
-		 not confused with a DOC file offset (the USE_LSB_TAG shift
-		 relies on the fact that VALMASK is one bit narrower than
-		 INTMASK).  Eventually Snarf-documentation should replace the
-		 placeholder with the actual docstring.  */
-	      verify (INTMASK & ~VALMASK);
-	      EMACS_UINT hash = ((XHASH (tmp) >> USE_LSB_TAG)
-				 | (INTMASK - INTMASK / 2));
-	      ASET (tmp, COMPILED_DOC_STRING, make_ufixnum (hash));
-	    }
-
 	  XSETPVECTYPE (vec, PVEC_COMPILED);
 	  return tmp;
 	}
@@ -4208,31 +4191,13 @@ read_list (bool flag, Lisp_Object readcharfun)
 
       /* While building, if the list starts with #$, treat it specially.  */
       if (EQ (elt, Vload_file_name)
-	  && ! NILP (elt)
-	  && !NILP (Vpurify_flag))
+	  && ! NILP (elt))
 	{
-	  if (NILP (Vdoc_file_name))
-	    /* We have not yet called Snarf-documentation, so assume
-	       this file is described in the DOC file
-	       and Snarf-documentation will fill in the right value later.
-	       For now, replace the whole list with 0.  */
-	    doc_reference = 1;
-	  else
-	    /* We have already called Snarf-documentation, so make a relative
-	       file name for this file, so it can be found properly
-	       in the installed Lisp directory.
-	       We don't use Fexpand_file_name because that would make
-	       the directory absolute now.  */
-	    {
-	      AUTO_STRING (dot_dot_lisp, "../lisp/");
-	      elt = concat2 (dot_dot_lisp, Ffile_name_nondirectory (elt));
-	    }
+	  if (!NILP (Vpurify_flag))
+	    doc_reference = 0;
+	  else if (load_force_doc_strings)
+	    doc_reference = 2;
 	}
-      else if (EQ (elt, Vload_file_name)
-	       && ! NILP (elt)
-	       && load_force_doc_strings)
-	doc_reference = 2;
-
       if (ch)
 	{
 	  if (flag > 0)
@@ -4253,8 +4218,6 @@ read_list (bool flag, Lisp_Object readcharfun)
 
 	      if (ch == ')')
 		{
-		  if (doc_reference == 1)
-		    return make_fixnum (0);
 		  if (doc_reference == 2 && FIXNUMP (XCDR (val)))
 		    {
 		      char *saved = NULL;




^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-29  0:15       ` Stefan Monnier
@ 2021-12-29 12:30         ` Johann Klähn
  2021-12-29 23:08           ` Stefan Monnier
  2021-12-29 12:52         ` Eli Zaretskii
  1 sibling, 1 reply; 31+ messages in thread
From: Johann Klähn @ 2021-12-29 12:30 UTC (permalink / raw)
  To: emacs-devel


Stefan Monnier <monnier@iro.umontreal.ca> writes:
> diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c
> index d17c28be90..4f4b135589 100644
> --- a/lib-src/make-docfile.c
> +++ b/lib-src/make-docfile.c
> @@ -20,7 +20,7 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
>  
>  
>  /* The arguments given to this program are all the C and Lisp source files

Maybe also remove the "Lisp source files" part here?




^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-29  0:15       ` Stefan Monnier
  2021-12-29 12:30         ` Johann Klähn
@ 2021-12-29 12:52         ` Eli Zaretskii
  2021-12-29 23:23           ` Stefan Monnier
  1 sibling, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2021-12-29 12:52 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel, akrl

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: Andrea Corallo <akrl@sdf.org>,  emacs-devel@gnu.org
> Date: Tue, 28 Dec 2021 19:15:11 -0500
> 
> Seeing how I haven't heard any opposition to the idea, I fixed a few
> loose ends, and I think it's now ready.  See below.
> Any objection?

This seems to do much more than just what you said, even if I include
the obvious cleanups, like unnecessary variables and support code no
longer required.  Are all the changes really necessary/derived, or did
you take the chance to make some additional changes, which should
perhaps be discussed separately?

>    When Emacs starts up, it sets up the value of @code{load-path}
> -in several steps.  First, it initializes @code{load-path} using
> -default locations set when Emacs was compiled.  Normally, this
> -is a directory something like
> +in several steps.  First, it initializes @code{lisp-directory} using
> +default locations set when Emacs was compiled.

You used for lisp-directory the same words as we used for load-path,
but is that the correct description?  Looking at the code that
computes the value of lisp-directory, I don't think so, I think you
can say something much more accurate and explicit about
lisp-directory.

Moreover, the text about load-path is now completely gone, and that is
a net loss, I think.

> +@defvar lisp-directory
> +Name of the directory holding Emacs's bundled Lisp files.

This is not accurate enough, given that it could mean both the place
where Emacs was built (the "bundled" part can be interpreted that
way), the place where *.el and *.elc files are installed when the
built Emacs is being installed, and the place where the *.eln files
are installed.

> +Normally, this is a directory something like
>  @example
>  "/usr/local/share/emacs/@var{version}/lisp"
>  @end example

This should tell what does @var{version} stand for.

> ++++
> +** New variable 'lisp-directory' holds the directory of Emacs's own Lisp files.

This suffers from the same accuracy problems.

> +(defvar lisp-directory nil
> +  "Directory containing the Lisp files that come with GNU Emacs.")

Likewise.  Actually, "files that come with GNU Emacs" is even worse in
its ambiguity than "bundled".

And why isn't the main part of the change called out in NEWS?  I think
this is something we should announce.

Thanks.



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-29 12:30         ` Johann Klähn
@ 2021-12-29 23:08           ` Stefan Monnier
  0 siblings, 0 replies; 31+ messages in thread
From: Stefan Monnier @ 2021-12-29 23:08 UTC (permalink / raw)
  To: Johann Klähn; +Cc: emacs-devel

> Maybe also remove the "Lisp source files" part here?

Indeed, thanks,


        Stefan




^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-29 12:52         ` Eli Zaretskii
@ 2021-12-29 23:23           ` Stefan Monnier
  2021-12-30  7:20             ` Eli Zaretskii
  0 siblings, 1 reply; 31+ messages in thread
From: Stefan Monnier @ 2021-12-29 23:23 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: akrl, emacs-devel

>> Seeing how I haven't heard any opposition to the idea, I fixed a few
>> loose ends, and I think it's now ready.  See below.
>> Any objection?
> This seems to do much more than just what you said, even if I include
> the obvious cleanups, like unnecessary variables and support code no
> longer required.  Are all the changes really necessary/derived, or did
> you take the chance to make some additional changes, which should
> perhaps be discussed separately?

I don't think this includes any unrelated change.  I know I have
a tendency to do that even without noticing it, but I tried to be
careful this time.

Some of the needed changes could be done differently (mostly the
changes that revolve around the use of relative file names), I guess,
but it's all either needed or subsequent obvious cleanup.

>>    When Emacs starts up, it sets up the value of @code{load-path}
>> -in several steps.  First, it initializes @code{load-path} using
>> -default locations set when Emacs was compiled.  Normally, this
>> -is a directory something like
>> +in several steps.  First, it initializes @code{lisp-directory} using
>> +default locations set when Emacs was compiled.
> You used for lisp-directory the same words as we used for load-path,
> but is that the correct description?

Good question.  I think it should (as in, any difference is likely
a sign of a bug), tho I haven't looked closely at the code to see if the
code matches this expectation.

> Looking at the code that computes the value of lisp-directory, I don't
> think so, I think you can say something much more accurate and
> explicit about lisp-directory.

Don't know what that would look like.

> Moreover, the text about load-path is now completely gone, and that is
> a net loss, I think.

I don't see it being gone.  But yes, I'm not super happy with the text
I have.  I already rewrote it three times before the version you saw.
I'd appreciate some help with it.

>> +@defvar lisp-directory
>> +Name of the directory holding Emacs's bundled Lisp files.
> This is not accurate enough, given that it could mean both the place
> where Emacs was built (the "bundled" part can be interpreted that
> way), the place where *.el and *.elc files are installed when the
> built Emacs is being installed, and the place where the *.eln files
> are installed.

Hmm.. not sure how to avoid those problems: mentioning what it is not
would seem to muddy the waters even further.

>> +Normally, this is a directory something like
>>  @example
>>  "/usr/local/share/emacs/@var{version}/lisp"
>>  @end example
> This should tell what does @var{version} stand for.

(apparently like the author of that chunk) I don't see why that
would be necessary.

> Likewise.  Actually, "files that come with GNU Emacs" is even worse in
> its ambiguity than "bundled".

Any suggestion for a better wording?

> And why isn't the main part of the change called out in NEWS?
> I think this is something we should announce.

AFAIK it's invisible to the end user, so I think it isn't worth
mentioning there.


        Stefan




^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-29 23:23           ` Stefan Monnier
@ 2021-12-30  7:20             ` Eli Zaretskii
  2021-12-31  4:19               ` Stefan Monnier
  0 siblings, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2021-12-30  7:20 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel, akrl

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: akrl@sdf.org,  emacs-devel@gnu.org
> Date: Wed, 29 Dec 2021 18:23:32 -0500
> 
> >>    When Emacs starts up, it sets up the value of @code{load-path}
> >> -in several steps.  First, it initializes @code{load-path} using
> >> -default locations set when Emacs was compiled.  Normally, this
> >> -is a directory something like
> >> +in several steps.  First, it initializes @code{lisp-directory} using
> >> +default locations set when Emacs was compiled.
> > You used for lisp-directory the same words as we used for load-path,
> > but is that the correct description?
> 
> Good question.  I think it should (as in, any difference is likely
> a sign of a bug), tho I haven't looked closely at the code to see if the
> code matches this expectation.

load-path is a list, whereas lisp-directory is a single directory.
So we could describe the latter much more accurately.

> > Looking at the code that computes the value of lisp-directory, I don't
> > think so, I think you can say something much more accurate and
> > explicit about lisp-directory.
> 
> Don't know what that would look like.

Some text which says what its value should be, or where it should
point.

> > Moreover, the text about load-path is now completely gone, and that is
> > a net loss, I think.
> 
> I don't see it being gone.  But yes, I'm not super happy with the text
> I have.  I already rewrote it three times before the version you saw.
> I'd appreciate some help with it.

I'm trying to help ;-)

If you need more specific help, please show the text you'd like to
improve and tell why you are unhappy with it, and I will try to help
more.

> >> +@defvar lisp-directory
> >> +Name of the directory holding Emacs's bundled Lisp files.
> > This is not accurate enough, given that it could mean both the place
> > where Emacs was built (the "bundled" part can be interpreted that
> > way), the place where *.el and *.elc files are installed when the
> > built Emacs is being installed, and the place where the *.eln files
> > are installed.
> 
> Hmm.. not sure how to avoid those problems: mentioning what it is not
> would seem to muddy the waters even further.

Why not say that it points to where the *.el and *.elc files are
installed in the Emacs installation tree?

> >> +Normally, this is a directory something like
> >>  @example
> >>  "/usr/local/share/emacs/@var{version}/lisp"
> >>  @end example
> > This should tell what does @var{version} stand for.
> 
> (apparently like the author of that chunk) I don't see why that
> would be necessary.

I beg to disagree.  We always describe every @var meta-syntactic
variable in our docs.  It takes just one short sentence to do that in
this case.

> > Likewise.  Actually, "files that come with GNU Emacs" is even worse in
> > its ambiguity than "bundled".
> 
> Any suggestion for a better wording?

See above: mention the installation tree and the files in that
directory explicitly.

> > And why isn't the main part of the change called out in NEWS?
> > I think this is something we should announce.
> 
> AFAIK it's invisible to the end user, so I think it isn't worth
> mentioning there.

NEWS are not just for users, they are also for Lisp programmers.  We
have specialized sections there for that very reason.



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-30  7:20             ` Eli Zaretskii
@ 2021-12-31  4:19               ` Stefan Monnier
  2021-12-31  8:57                 ` Eli Zaretskii
  0 siblings, 1 reply; 31+ messages in thread
From: Stefan Monnier @ 2021-12-31  4:19 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: akrl, emacs-devel

> I'm trying to help ;-)

OK, after re-reading the section a few times and rewriting it a couple
more, I think I got something vaguely acceptable.


        Stefan




^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-31  4:19               ` Stefan Monnier
@ 2021-12-31  8:57                 ` Eli Zaretskii
  2021-12-31 16:16                   ` Stefan Monnier
  0 siblings, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2021-12-31  8:57 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel, akrl

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: akrl@sdf.org,  emacs-devel@gnu.org
> Date: Thu, 30 Dec 2021 23:19:43 -0500
> 
> > I'm trying to help ;-)
> 
> OK, after re-reading the section a few times and rewriting it a couple
> more, I think I got something vaguely acceptable.

Thanks, I have one question: if EMACSLOADPATH is set in the
environment, does it affect the value of lisp-directory?  Should it?



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-31  8:57                 ` Eli Zaretskii
@ 2021-12-31 16:16                   ` Stefan Monnier
  2021-12-31 18:45                     ` Eli Zaretskii
  0 siblings, 1 reply; 31+ messages in thread
From: Stefan Monnier @ 2021-12-31 16:16 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: akrl, emacs-devel

>> OK, after re-reading the section a few times and rewriting it a couple
>> more, I think I got something vaguely acceptable.
> Thanks, I have one question: if EMACSLOADPATH is set in the
> environment, does it affect the value of lisp-directory?

I don't know: I did not write the code that computes this directory,
because it was already written for the purpose of making absolute the
filenames of preloaded files in `load-history`.

> Should it?

Maybe/probably, but since EMACSLOADPATH is a list of directories I'm not
sure how to make it reliable.  Maybe it should look for some
"well-known" bundled ELisp file in EMACSLOADPATH an derive the value of
`lisp-directory` from it?


        Stefan




^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-31 16:16                   ` Stefan Monnier
@ 2021-12-31 18:45                     ` Eli Zaretskii
  0 siblings, 0 replies; 31+ messages in thread
From: Eli Zaretskii @ 2021-12-31 18:45 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel, akrl

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: akrl@sdf.org,  emacs-devel@gnu.org
> Date: Fri, 31 Dec 2021 11:16:47 -0500
> 
> >> OK, after re-reading the section a few times and rewriting it a couple
> >> more, I think I got something vaguely acceptable.
> > Thanks, I have one question: if EMACSLOADPATH is set in the
> > environment, does it affect the value of lisp-directory?
> 
> I don't know: I did not write the code that computes this directory,
> because it was already written for the purpose of making absolute the
> filenames of preloaded files in `load-history`.

So if EMACSLOADPATH is set, the lisp-directory variable will not be
currently set?

> > Should it?
> 
> Maybe/probably, but since EMACSLOADPATH is a list of directories I'm not
> sure how to make it reliable.  Maybe it should look for some
> "well-known" bundled ELisp file in EMACSLOADPATH an derive the value of
> `lisp-directory` from it?

Yes, I think so.



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2021-12-28  1:48 Not using DOC for ELisp files Stefan Monnier
                   ` (3 preceding siblings ...)
  2021-12-28 12:44 ` Eli Zaretskii
@ 2022-01-03 13:48 ` Ken Raeburn
  2022-01-03 14:30   ` Eli Zaretskii
  4 siblings, 1 reply; 31+ messages in thread
From: Ken Raeburn @ 2022-01-03 13:48 UTC (permalink / raw)
  To: emacs-devel

On 2021-12-27 20:48, Stefan Monnier wrote:
> The patch below removes from the DOC file the docstrings coming from
> ELisp files.
>
> In numbers (in my tests), this reduces the size of DOC from about 3.2MB
> to about 850kB, and increases the pdmp size by about 53kB or about 0.7%.
>
> The benefits aren't great, obviously, but it does remove some warts in
> the `lread.c` code (into which I bumped in the `scratch/fcr` branch,
> which is why this comes up now).
>
> I have a vague recollection that such a change was mentioned in some
> bugreport-discussion some months ago but I can't remember where.
>
> Comments?


I've only skimmed the actual code changes so far, but I think this is a 
good direction to go.

Stefan Kargas dug up an old bug report of mine, but I think I may also 
have mentioned something like this in our old discussion and 
experimentation of doing away with unexec in favor of a big .elc file, a 
few years back now(!), my idea at the time being to reduce the runtime 
startup work done in a build without unexec.

Another piece I recall looking at, which I don't remember if I brought 
up on the list at the time, was moving the C based doc strings into the 
generated .o files and the executable; in combination with removing the 
elisp doc strings, this would get rid of the DOC file altogether. I 
haven't had much time for Emacs hacking in quite a while, sadly, but if 
there's interest, I can try to find a little time to dig up those old 
changes on the C side and see how complete they were and if they can 
still be adapted in some form or other...

Ken




^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2022-01-03 13:48 ` Ken Raeburn
@ 2022-01-03 14:30   ` Eli Zaretskii
  2022-01-07 22:59     ` Ken Raeburn
  0 siblings, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2022-01-03 14:30 UTC (permalink / raw)
  To: Ken Raeburn; +Cc: emacs-devel

> Date: Mon, 3 Jan 2022 08:48:03 -0500
> From: Ken Raeburn <raeburn@raeburn.org>
> 
> Another piece I recall looking at, which I don't remember if I brought 
> up on the list at the time, was moving the C based doc strings into the 
> generated .o files and the executable

Did you only think about ELF executables, or did you consider how to
do this with any binary formats we support?



^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2022-01-03 14:30   ` Eli Zaretskii
@ 2022-01-07 22:59     ` Ken Raeburn
  2022-01-08  7:08       ` Eli Zaretskii
  0 siblings, 1 reply; 31+ messages in thread
From: Ken Raeburn @ 2022-01-07 22:59 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

On 2022-01-03 09:30, Eli Zaretskii wrote:
>> Date: Mon, 3 Jan 2022 08:48:03 -0500
>> From: Ken Raeburn <raeburn@raeburn.org>
>>
>> Another piece I recall looking at, which I don't remember if I brought
>> up on the list at the time, was moving the C based doc strings into the
>> generated .o files and the executable
> Did you only think about ELF executables, or did you consider how to
> do this with any binary formats we support?

As I recall, it was a generic approach, putting the strings into char 
arrays linked in at the C level during compilation. For variables, I 
think there was some indirection via an array index, to avoid increasing 
Lisp_Symbol size while also not creating all the doc strings as Lisp 
strings up front. I don't recall if that part got completed; I tackled 
function docs first.

The annoying part was, it adds a generated header per C source file for 
these strings. I was looking at whether it could be done without doing 
so, but make-docfile tacks on the "(fn THIS-ARG THAT-ARG ...)" bit for 
function documentation which can't _exactly_ be done with preprocessor 
hacks; cpp has no "upcase" function, though tweaks to the runtime 
support could work around that. And DEFVAR docs need to be pulled out 
and (as mentioned above) stuffed into an array of strings.

There was an optimization I did, for platforms supporting the "section" 
attribute extension (at least MacOS and the GNU tools on ELF), to group 
together the strings in the object file (and hopefully the executable) 
so that, if the doc strings weren't actually used, none of those pages 
need be paged in from disk, because they aren't intermixed with other 
data (except maybe at the ends of the range). But if that support isn't 
available, the rest should still work fine. And if the non-Lisp doc 
strings amount to less than a megabyte, as I think an earlier email in 
this thread indicated, the memory cost of not doing this apparently 
isn't huge anyway.

Ken




^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: Not using DOC for ELisp files
  2022-01-07 22:59     ` Ken Raeburn
@ 2022-01-08  7:08       ` Eli Zaretskii
  0 siblings, 0 replies; 31+ messages in thread
From: Eli Zaretskii @ 2022-01-08  7:08 UTC (permalink / raw)
  To: Ken Raeburn; +Cc: emacs-devel

> Date: Fri, 7 Jan 2022 17:59:25 -0500
> Cc: emacs-devel@gnu.org
> From: Ken Raeburn <raeburn@raeburn.org>
> 
> There was an optimization I did, for platforms supporting the "section" 
> attribute extension (at least MacOS and the GNU tools on ELF), to group 
> together the strings in the object file (and hopefully the executable) 
> so that, if the doc strings weren't actually used, none of those pages 
> need be paged in from disk, because they aren't intermixed with other 
> data (except maybe at the ends of the range). But if that support isn't 
> available, the rest should still work fine. And if the non-Lisp doc 
> strings amount to less than a megabyte, as I think an earlier email in 
> this thread indicated, the memory cost of not doing this apparently 
> isn't huge anyway.

Beware: adding new sections to the binary causes problems when the
binary is stripped.



^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2022-01-08  7:08 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-12-28  1:48 Not using DOC for ELisp files Stefan Monnier
2021-12-28  2:25 ` Po Lu
2021-12-28  3:48   ` Stefan Kangas
2021-12-28  5:39     ` Po Lu
2021-12-28  4:11   ` LdBeth
2021-12-28  5:03     ` Stefan Monnier
2021-12-28  5:38     ` Po Lu
2021-12-28  9:52     ` Phil Sainty
2021-12-28 10:31       ` Po Lu
2021-12-28 12:47         ` Po Lu
2021-12-28  7:10   ` Lars Ingebrigtsen
2021-12-28  3:39 ` Stefan Kangas
2021-12-28  5:10   ` Stefan Monnier
2021-12-28  6:56 ` Lars Ingebrigtsen
2021-12-28 12:44 ` Eli Zaretskii
2021-12-28 17:14   ` Stefan Monnier
2021-12-28 18:17     ` Eli Zaretskii
2021-12-29  0:15       ` Stefan Monnier
2021-12-29 12:30         ` Johann Klähn
2021-12-29 23:08           ` Stefan Monnier
2021-12-29 12:52         ` Eli Zaretskii
2021-12-29 23:23           ` Stefan Monnier
2021-12-30  7:20             ` Eli Zaretskii
2021-12-31  4:19               ` Stefan Monnier
2021-12-31  8:57                 ` Eli Zaretskii
2021-12-31 16:16                   ` Stefan Monnier
2021-12-31 18:45                     ` Eli Zaretskii
2022-01-03 13:48 ` Ken Raeburn
2022-01-03 14:30   ` Eli Zaretskii
2022-01-07 22:59     ` Ken Raeburn
2022-01-08  7:08       ` Eli Zaretskii

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).