Subject: Re: bug#16526: 24.3.50; scroll-conservatively & c-mode regression

From: Eli Zaretskii <[email-masked]>
Date: Mon, 27 Jan 2014 18:23:02 +0200

> Date: Mon, 27 Jan 2014 09:20:57 +0100
> From: martin rudalics <[email-masked]>
> CC: [email-masked], [email-masked]
> 
> Well... try_scrolling could detect that `point' is some 15000 lines away
> from the current window start so trying to scroll the window as little
> as possible might not be worth the effort.

How would it detect that, except using the same method it uses now?
Note that we are not talking physical lines in the buffer here, we are
talking screen lines.  Actually, not even that: we are talking
_canonical_ screen lines, i.e. practically pixels.  Now, those 15000
lines could well be covered by an invisible property, or by a display
property that displays something other than buffer text.  Or they
could use a face that calls for a very small font, so that all the
15000 lines take very little screen estate.  In all of these cases, a
user who sets scroll-conservatively to 101 wants the screen scrolled
rather than recentered.  So that's what try_scrolling tries to do.
It's why that function exists.

However, try_scrolling's search is limited, so it normally fails very
quickly.  Except that in this case, the code invoked by JIT Lock hogs
the CPU for a very long time.

>  > And here's where things go awry: For some reason, the CC Mode
>  > fontification code decides it needs to scan the buffer backwards,
>  > starting from EOB.  So it goes temporarily to EOB (this is why I saw
>  > point being there), and scans all the way back, I think in this loop
>  > from c-append-lower-brace-pair-to-state-cache, which is called with
>  > its first argument FROM set to EOB:
> 
> But it's redisplay which temporarily puts `point' at EOB and triggers
> the fontification subsystem to "work" at that position?

No, redisplay doesn't change point, not ever.  It's cc-engine's
routines that do it in this case, and I've shown where in the code
that happens, see the backtrace I posted.

>  > This loop takes a lot of time, of course, and is a waste of time,
>  > since eventually try_scrolling comes to the correct conclusion that
>  > scrolling is impossible, and instead recenters at BOB.
> 
> Are you sure that try_scrolling doesn't call this loop over and over
> again?

Sorry, I don't understand the question.  try_scrolling doesn't include
any loops where all this happens, it just calls move_it_to, a single
call.  All the rest happens inside that call.  Normally, that call
should just descend a few screen lines starting at point (which is at
BOB), until it hits the limit I mentioned above, and then
try_scrolling should return a failure indication.

I did verify that there's a single call to move_it_to, and that all
the time you wait is spent inside that call.

>  > Why does CC Mode decide to go from EOB backwards, I don't know;
>  > presumably, this is decided by c-parse-state-get-strategy as part of
>  > c-parse-state-1.
> 
> This seems obvious.  To decide whether code shall be fontified this way
> or another it has to decide whether the code is part of a comment and
> find that comment's start.  As long as it is not aware of the fact that
> `point' is already at BOB, obviously.

Why shouldn't CC Mode be aware that point is at BOB?  It has just to
look at its value.