From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.bugs Subject: bug#16526: 24.3.50; scroll-conservatively & c-mode regression Date: Wed, 29 Jan 2014 21:52:40 +0000 Message-ID: <20140129215240.GC3092@acm.acm> References: <52E3D131.2090705@gmx.at> <83r47wausm.fsf@gnu.org> <52E3EAC2.2040100@gmx.at> <83lhy4as2l.fsf@gnu.org> <52E4019C.5080905@gmx.at> <83k3dnc3rl.fsf@gnu.org> <83iot7c3bq.fsf@gnu.org> <52E4EF61.3050404@gmx.at> <831tzubqxw.fsf@gnu.org> <20140126204310.GA3937@acm.acm> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1391032582 28662 80.91.229.3 (29 Jan 2014 21:56:22 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 29 Jan 2014 21:56:22 +0000 (UTC) Cc: 16526@debbugs.gnu.org To: Eli Zaretskii , martin rudalics Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Jan 29 22:56:28 2014 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1W8d7U-0006OW-20 for geb-bug-gnu-emacs@m.gmane.org; Wed, 29 Jan 2014 22:56:28 +0100 Original-Received: from localhost ([::1]:45424 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W8d7T-0002y8-D0 for geb-bug-gnu-emacs@m.gmane.org; Wed, 29 Jan 2014 16:56:27 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:38896) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W8d7K-0002wX-CD for bug-gnu-emacs@gnu.org; Wed, 29 Jan 2014 16:56:25 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W8d7D-0007hO-0S for bug-gnu-emacs@gnu.org; Wed, 29 Jan 2014 16:56:18 -0500 Original-Received: from debbugs.gnu.org ([140.186.70.43]:54933) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W8d74-0007bt-Ng; Wed, 29 Jan 2014 16:56:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1W8d74-0002e0-1S; Wed, 29 Jan 2014 16:56:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Alan Mackenzie Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org, bug-cc-mode@gnu.org Resent-Date: Wed, 29 Jan 2014 21:56:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 16526 X-GNU-PR-Package: emacs,cc-mode X-GNU-PR-Keywords: Original-Received: via spool by 16526-submit@debbugs.gnu.org id=B16526.139103256010157 (code B ref 16526); Wed, 29 Jan 2014 21:56:01 +0000 Original-Received: (at 16526) by debbugs.gnu.org; 29 Jan 2014 21:56:00 +0000 Original-Received: from localhost ([127.0.0.1]:40719 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1W8d72-0002dk-2Q for submit@debbugs.gnu.org; Wed, 29 Jan 2014 16:56:00 -0500 Original-Received: from colin.muc.de ([193.149.48.1]:63490 helo=mail.muc.de) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1W8d6y-0002db-Mh for 16526@debbugs.gnu.org; Wed, 29 Jan 2014 16:55:58 -0500 Original-Received: (qmail 4520 invoked by uid 3782); 29 Jan 2014 21:55:55 -0000 Original-Received: from acm.muc.de (pD95197D0.dip0.t-ipconnect.de [217.81.151.208]) by colin.muc.de (tmda-ofmipd) with ESMTP; Wed, 29 Jan 2014 22:55:54 +0100 Original-Received: (qmail 4578 invoked by uid 1000); 29 Jan 2014 21:52:40 -0000 Content-Disposition: inline In-Reply-To: <20140126204310.GA3937@acm.acm> User-Agent: Mutt/1.5.21 (2010-09-15) X-Delivery-Agent: TMDA/1.1.12 (Macallan) X-Primary-Address: acm@muc.de X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:84229 Archived-At: Hello, Eli, hello, Martin. On Sun, Jan 26, 2014 at 08:43:10PM +0000, Alan Mackenzie wrote: > On Sun, Jan 26, 2014 at 07:20:27PM +0200, Eli Zaretskii wrote: > > You are right, sorry. (I wasn't wrong, either: recenter does call the > > same find_defun_start around EOB, which is what I saw. But those > > calls are very few and aren't responsible for the slowdown. I also > > wasn't wrong about point being at EOB, see below. But I described > > what happens incorrectly.) > > Here's what I see in the debugger: > > After beginning-of-buffer jumps to point-min, redisplay kicks in. > > Since scroll-conservatively is set to a large value, redisplay first > > tries to see whether it can bring point into view by scrolling the > > window as little as possible. It calls try_scrolling, which at some > > point (around line 15000) tries to see whether the new location of > > point is close enough to the current window start. It does so by > > calling move_it_to, which simulates the display. While doing so, > > move_it_to hits a portion of text with font-lock properties, and calls > > JIT Lock to fontify them. > > 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. > The @dfn{state cache}, a list of certain brace/paren/bracket positions > around some position, is set for a position near EOB. With the switch to > a different position, CC Mode tweaks the state cache rather than > calculating it anew starting at BOB. When the new position is nearer > BOB, the code searches backwards for the appropriate braces. However, it > shouldn't be scanning the entire buffer backwards. There is clearly a > bug here. > > 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: > > ;; In the next pair of nested loops, the inner one moves back past a > > ;; pair of (mis-)matching parens or brackets; the outer one moves > > ;; back over a sequence of unmatched close brace/paren/bracket each > > ;; time round. > > (while > > (progn > > (c-safe > > (while > > (and (setq ce (scan-lists bra -1 -1)) ; back past )/]/}; might signal > > (setq bra (scan-lists ce -1 1)) ; back past (/[/{; might signal > > (or (> bra here) ;(> ce here) > > (and > > (< ce here) > > (or (not (eq (char-after bra) ?\{)) > > (and (goto-char bra) > > (c-beginning-of-macro) > > (< (point) macro-start-or-from)))))))) > > (and ce (< ce bra))) > > (setq bra ce)) ; If we just backed over an unbalanced closing > > ; brace, ignore it. > The backward scan-lists calls will be causing continual forward searches > from BOB in syntax.c, every time the backward scan hits a comment ender. > > 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. > > 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. > Yes. There is a bug here. I have a strong suspicion where. > [ .... ] > > I hope this information will allow Alan to find the culprit and solve > > the problem. > Yes indeed, thanks. But I'm not going to be able to resolve it in a > scale of hours. It's going to be days. Sorry! OK, here is a rough patch (smooth version to follow if it's any good), which attempts to solve the problem by not calling c-append-lower-brace-pair-to-state-cache in the pertinent circumstances. Please try it out and let me know if it solves the problem (I still can't reproduce the massive slowdown myself). diff -r d6064f65b0a1 cc-engine.el --- a/cc-engine.el Sun Jan 19 12:09:59 2014 +0000 +++ b/cc-engine.el Wed Jan 29 21:17:50 2014 +0000 @@ -2556,6 +2556,8 @@ ;; o - ('forward START-POINT) - scan forward from START-POINT, ;; which is not less than the highest position in `c-state-cache' below here. ;; o - ('backward nil) - scan backwards (from HERE). + ;; o - ('back-and-forward START-POINT) - like 'forward, but when HERE is earlier + ;; than GOOD-POS. ;; o - ('IN-LIT nil) - point is inside the literal containing point-min. (let ((cache-pos (c-get-cache-scan-pos here)) ; highest position below HERE in cache (or 1) strategy ; 'forward, 'backward, or 'IN-LIT. @@ -2570,9 +2572,10 @@ ((< (- good-pos here) (- here cache-pos)) ; FIXME!!! ; apply some sort of weighting. (setq strategy 'backward)) (t - (setq strategy 'forward + (setq strategy 'back-and-forward start-point cache-pos))) - (list strategy (and (eq strategy 'forward) start-point)))) + (list strategy ;(and (eq strategy 'forward) + start-point)));) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -2857,7 +2860,7 @@ ;; adjust it to get outside a string/comment. (Sorry about this! The code ;; needs to be FAST). ;; - ;; Return a list (GOOD-POS SCAN-BACK-POS PPS-STATE), where + ;; Return a list (GOOD-POS SCAN-BACK-POS PPS-STATE), where FIXME!!! ;; o - GOOD-POS is a position where the new value `c-state-cache' is known ;; to be good (we aim for this to be as high as possible); ;; o - SCAN-BACK-POS, if not nil, indicates there may be a brace pair @@ -2892,6 +2895,7 @@ pos upper-lim ; ,beyond which `c-state-cache' entries are removed scan-back-pos + cons-separated pair-beg pps-point-state target-depth) ;; Remove entries beyond HERE. Also remove any entries inside @@ -2913,7 +2917,8 @@ (consp (car c-state-cache)) (> (cdar c-state-cache) upper-lim)) (setcar c-state-cache (caar c-state-cache)) - (setq scan-back-pos (car c-state-cache))) + (setq scan-back-pos (car c-state-cache) + cons-separated t)) ;; The next loop jumps forward out of a nested level of parens each ;; time round; the corresponding elements in `c-state-cache' are @@ -2986,7 +2991,8 @@ (setq c-state-cache (cons (cons pair-beg pos) c-state-cache))) - (list pos scan-back-pos pps-state))))) + ;(when (< pos scan-back-pos) (setq scan-back-pos nil)) ; 2014-01-26 FIXME!!! + (list pos scan-back-pos pps-state cons-separated))))) (defun c-remove-stale-state-cache-backwards (here) ;; Strip stale elements of `c-state-cache' by moving backwards through the @@ -3271,6 +3277,7 @@ ; are no open parens/braces between it and HERE. bopl-state res + cons-separated scan-backward-pos scan-forward-p) ; used for 'backward. ;; If POINT-MIN has changed, adjust the cache (unless (= (point-min) c-state-point-min) @@ -3283,13 +3290,15 @@ ;; SCAN! (cond - ((eq strategy 'forward) + ((memq strategy '(forward back-and-forward)) ;(eq strategy 'forward) (setq res (c-remove-stale-state-cache start-point here here-bopl)) (setq cache-pos (car res) scan-backward-pos (cadr res) - bopl-state (car (cddr res))) ; will be nil if (< here-bopl + bopl-state (car (cddr res)) ; will be nil if (< here-bopl ; start-point) - (if scan-backward-pos + cons-separated (car (cdddr res))) + (if (and scan-backward-pos + (or cons-separated (eq strategy 'forward))) ;scan-backward-pos (c-append-lower-brace-pair-to-state-cache scan-backward-pos here)) (setq good-pos (c-append-to-state-cache cache-pos here)) -- Alan Mackenzie (Nuremberg, Germany).