Subject: Re: bug#78898: Make read/readevalloop reentrant

From: Lynn Winebarger <[email-masked]>
Date: Tue, 15 Jul 2025 23:46:45 -0400

On Sun, Jun 29, 2025 at 1:03 PM Stefan Monnier <[email-masked]> wrote:
>
>
> I can definitely go along with that.  The reason why I care so much
> about the motivation behind the change is that it affects the tradeoffs
> (e.g. impact on performance or code maintenance).  Have you made any
> measurements about the impact on the speed for `read`?
> Emacs startup time is significantly affected by the time to `read`.
>
I've modified the build process to retain profiling data generated
from using the --enable-profiling option.  See bug#79001: "Retain
profile image files generated during build" for a patch.  I built
emacs for commit 2bdcf0250acecdb0719203ae711aedf5baad1783 as the
baseline and then that commit + the last patchset I provided using:
CC=/usr/local/bin/gcc \
     LD=/usr/local/bin/ld \
     PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig \
    ../configure --enable-checking='yes,glyphs'
--enable-check-lisp-object-type  \
    CFLAGS='-O0 -g3 -gdwarf-5 -fvar-tracking -gstatement-frontiers' \
    --infodir=/usr/local/share/emacs/31/share/info \
    --mandir=/usr/local/share/emacs/31/share/man \
    --docdir=/usr/local/share/emacs/31/share/doc/emacs \
    --localedir=/usr/local/share/emacs/31/share/locale \
    --with-x --with-xim --with-sound --with-xpm --with-jpeg \
    --with-tiff --with-gif --with-png --with-rsvg --with-imagemagick \
    --with-dbus --with-gpm --with-x-toolkit=gtk3 --with-toolkit-scroll-bars \
    --with-libotf --with-m17n-flt --with-cairo  --with-xwidgets \
    --disable-build-details --without-pop --with-mailutils --without-hesiod \
    --with-gameuser=:games --with-kerberos --with-kerberos5 \
    --with-file-notification=inotify --with-modules --with-tree-sitter \
    --with-native-compilation=no --enable-profiling=all
make -j $(nproc) PROFILE_BUILD=yes

The list of ELC jobs run in the BUILD/lisp directory is given in the
attached ELC-gmon-out-files.txt for reference.  I summarized them
using gprof -s, then produced 4 analysis output files for each (hence
8 attached) in BUILD/lisp:

Just the lread functions:
gprof --flat-profile=lread.c ../src/temacs temacs-gmon-ELC.sum
>../ELC-lread-flat-profile-<id>.txt
gprof --graph=lread.c -k lread.c/eval.c ../src/temacs
temacs-gmon-ELC.sum >../ELC-lread-call-graph-<id>.txt

These are for reference - the functions of lread.c only consume about
1.5-2% of the total profile time according to these:
gprof --flat-profile ../src/temacs temacs-gmon-ELC.sum
>../ELC-flat-profile-<id>.txt
gprof --graph ../src/temacs temacs-gmon-ELC.sum >../ELC-call-graph-<id>.txt

The identifiers are 2bdcf0250acecdb0719203ae711aedf5baad1783 for the
baseline and 2bdcf0250acecdb0719203ae711aedf5baad1783-reentrant-reader
for the patched version.
Since these are -O0 builds, it's hard to say too much for cases where
macros have been replaced by inline function calls.  For read0 itself,
there is an increase in "self-seconds" of 3%, presumably due to using
pointers into a data structure instead of static variables.  The same
comment applies to a number of other functions called by read0, but
the penalty for those appears substantially higher.

For some reason I do not understand, the time spent in oblookup
decreased by 9% after the patch.

At any rate, I don't want to spend too much effort plumbing these
results since Mattias has checked in some meaningful changes to
lread.c, so (among other things), after I rebase (or merge?) the patch
to a recent commit, at least there will be more inline function versus
inline function comparison, instead of inline versus macro.

Also, I should be able to make the patch from bug #79001 able to use
gcov or perf for profiling instead of gprof, if that would be of
interest, with fairly little effort.  With a bit of elbow grease, I
could make the elisp profiler run whenever some environment variable
like ELISP_MON_OUT is defined (with the output file name to use), that
could run at the same time as gcov is in effect, I think.

Lynn