Subject: Re: bug#57207: 29.0.50; Fontification is slow after e7b5912b23 (Improvements to long lines handling)

From: Eli Zaretskii <[email-masked]>
Date: Tue, 16 Aug 2022 14:55:56 +0300

> Date: Tue, 16 Aug 2022 10:47:00 +0000
> From: Gregory Heytings <[email-masked]>
> cc: [email-masked], [email-masked]
> 
> > Gregory, I suspect that the problem could be in the loop in 
> > redisplay_window, where we look for long lines.  Changing visibility in 
> > Org changes text properties, and that causes MODIFF to be incremented. 
> > I actually can cause something similar without Org at all, just by 
> > scrolling fast through xdisp.c.  You can put a breakpoint inside the 
> > 'if' that guards the re-evaluation of the long-lines in 
> > redisplay_window, and scroll with C-v through xdisp.c immediately after 
> > visiting it -- I hit the breakpoint from time to time, although there 
> > are no changes to the buffer except faces placed by fontifications.
> >
> > jit-lock runs under with-silent-modifications, but that only adjusts 
> > SAVE_MODIFF to create an illusion of unchanged buffer, it doesn't affect 
> > UNCHANGED_MODIFIED.
> >
> 
> Indeed, that's problematic: modify_text_properties calls modiff_incr 
> (&MODIFF, 1).  I think the safest change would be to use CHARS_MODIFF 
> instead of MODIFF, see attached.

As I said earlier, I've changed my mind about this after I wrote the
above.  We update UNCHANGED_MODIFIED in mark_window_display_accurate_1, 
so if the window completes its redisplay cycle "normally", whatever
jit-lock does shouldn't matter for the next redisplay cycle, because
UNCHANGED_MODIFIED will be updated from MODIFF.

Maybe Org does something that frequently causes a window's redisplay
cycle to end prematurely, in which case the code that looks for long
lines could be called too frequently.  But in that case, your proposed
change will have the same problem, I think?

What I don't understand is why enlarging the value of the threshold
causes Emacs to "hang".  If it really is some kind of infloop, I
cannot understand how issues like outdated UNCHANGED_MODIFIED could
cause that only for some value of the threshold, but not for a smaller
value.  I thought perhaps there are lines longer than 10000
characters, but none beyond 100000, but this turns out to be false, so
with both values of the threshold that loop in redisplay_window should
have scanned the entire buffer top to bottom in both cases...

So I suspect something else is at work here.