Fix a cacheing bug, which led to inordinately slow c-beginning-of-defun.

* lisp/progmodes/cc-defs.el (c-self-bind-state-cache): New macro.

* lisp/progmodes/cc-engine.el (c-ssb-lit-begin): Always call c-parse-state
rather than just using the cache variable c-state-cache.
(c-syntactic-skip-backward): Invoke c-self-bind-state-cache to isolate calls
to c-parse-state from other uses of the parse state cache.

* lisp/progmodes/cc-cmds.el (c-beginning-of-defun, c-end-of-defun): Invoke
c-self-bind-state-cache around the processing, replacing flawed bindings of
c-state-cache.
This commit is contained in:
Alan Mackenzie 2016-03-14 21:44:11 +00:00
parent 0ce37eac45
commit 5cc6919308
3 changed files with 225 additions and 201 deletions

View file

@ -1594,11 +1594,12 @@ defun."
(c-region-is-active-p) (c-region-is-active-p)
(push-mark)) (push-mark))
(c-self-bind-state-cache ; We must not share with other users of c-state-cache.
(c-save-buffer-state (c-save-buffer-state
(beginning-of-defun-function end-of-defun-function (beginning-of-defun-function
end-of-defun-function
(start (point)) (start (point))
(paren-state (copy-tree (c-parse-state))) ; This must not share list (paren-state (c-parse-state))
; structure with other users of c-state-cache.
(orig-point-min (point-min)) (orig-point-max (point-max)) (orig-point-min (point-min)) (orig-point-max (point-max))
lim ; Position of { which has been widened to. lim ; Position of { which has been widened to.
where pos case-fold-search) where pos case-fold-search)
@ -1656,7 +1657,7 @@ defun."
(goto-char pos))) (goto-char pos)))
(c-keep-region-active) (c-keep-region-active)
(= arg 0))))) (= arg 0))))))
(defun c-forward-to-nth-EOF-} (n where) (defun c-forward-to-nth-EOF-} (n where)
;; Skip to the closing brace of the Nth function after point. If ;; Skip to the closing brace of the Nth function after point. If
@ -1718,11 +1719,13 @@ the open-parenthesis that starts a defun; see `beginning-of-defun'."
(c-region-is-active-p) (c-region-is-active-p)
(push-mark)) (push-mark))
(c-self-bind-state-cache ; c-state-cache's list structure must not be shared
; with other users.
(c-save-buffer-state (c-save-buffer-state
(beginning-of-defun-function end-of-defun-function (beginning-of-defun-function
end-of-defun-function
(start (point)) (start (point))
(paren-state (copy-tree (c-parse-state))) ; This must not share list (paren-state (c-parse-state))
; structure with other users of c-state-cache.
(orig-point-min (point-min)) (orig-point-max (point-max)) (orig-point-min (point-min)) (orig-point-max (point-max))
lim lim
where pos case-fold-search) where pos case-fold-search)
@ -1777,7 +1780,7 @@ the open-parenthesis that starts a defun; see `beginning-of-defun'."
(goto-char pos)))) (goto-char pos))))
(c-keep-region-active) (c-keep-region-active)
(= arg 0)))) (= arg 0)))))
(defun c-defun-name () (defun c-defun-name ()
"Return the name of the current defun, or NIL if there isn't one. "Return the name of the current defun, or NIL if there isn't one.

View file

@ -1258,7 +1258,8 @@ been put there by c-put-char-property. POINT remains unchanged."
(def-edebug-spec c-clear-char-property t) (def-edebug-spec c-clear-char-property t)
(def-edebug-spec c-clear-char-properties t) (def-edebug-spec c-clear-char-properties t)
(def-edebug-spec c-put-overlay t) (def-edebug-spec c-put-overlay t)
(def-edebug-spec c-delete-overlay t) ;)) (def-edebug-spec c-delete-overlay t)
(def-edebug-spec c-self-bind-state-cache t);))
;;; Functions. ;;; Functions.
@ -1397,6 +1398,26 @@ been put there by c-put-char-property. POINT remains unchanged."
(save-restriction (save-restriction
(widen) (widen)
(c-set-cpp-delimiters ,beg ,end))))) (c-set-cpp-delimiters ,beg ,end)))))
(defmacro c-self-bind-state-cache (&rest forms)
;; Bind the state cache to itself and execute the FORMS. It is assumed that no
;; buffer changes will happen in FORMS, and no hidden buffer changes which could
;; affect the parsing will be made by FORMS.
`(let ((c-state-cache (copy-tree c-state-cache))
(c-state-cache-good-pos c-state-cache-good-pos)
;(c-state-nonlit-pos-cache (copy-tree c-state-nonlit-pos-cache))
;(c-state-nonlit-pos-cache-limit c-state-nonlit-pos-cache-limit)
;(c-state-semi-nonlit-pos-cache (copy-treec c-state-semi-nonlit-pos-cache))
;(c-state-semi-nonlit-pos-cache-limit c-state-semi-nonlit-pos-cache)
(c-state-brace-pair-desert (copy-tree c-state-brace-pair-desert))
(c-state-point-min c-state-point-min)
(c-state-point-min-lit-type c-state-point-min-lit-type)
(c-state-point-min-lit-start c-state-point-min-lit-start)
(c-state-min-scan-pos c-state-min-scan-pos)
(c-state-old-cpp-beg c-state-old-cpp-beg)
(c-state-old-cpp-end c-state-old-cpp-end))
,@forms))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; The following macros are to be used only in `c-parse-state' and its ;; The following macros are to be used only in `c-parse-state' and its

View file

@ -4259,8 +4259,7 @@ comment at the start of cc-engine.el for more info."
(setq safe-pos-list (cdr safe-pos-list))) (setq safe-pos-list (cdr safe-pos-list)))
(unless (setq safe-pos (car-safe safe-pos-list)) (unless (setq safe-pos (car-safe safe-pos-list))
(setq safe-pos (max (or (c-safe-position (setq safe-pos (max (or (c-safe-position
(point) (or c-state-cache (point) (c-parse-state))
(c-parse-state)))
0) 0)
(point-min)) (point-min))
safe-pos-list (list safe-pos))) safe-pos-list (list safe-pos)))
@ -4308,6 +4307,7 @@ Non-nil is returned if the point moved, nil otherwise.
Note that this function might do hidden buffer changes. See the Note that this function might do hidden buffer changes. See the
comment at the start of cc-engine.el for more info." comment at the start of cc-engine.el for more info."
(c-self-bind-state-cache
(let ((start (point)) (let ((start (point))
state-2 state-2
;; A list of syntactically relevant positions in descending ;; A list of syntactically relevant positions in descending
@ -4408,7 +4408,7 @@ comment at the start of cc-engine.el for more info."
;; We might want to extend this with more useful return values in ;; We might want to extend this with more useful return values in
;; the future. ;; the future.
(/= (point) start))) (/= (point) start))))
;; The following is an alternative implementation of ;; The following is an alternative implementation of
;; `c-syntactic-skip-backward' that uses backward movement to keep ;; `c-syntactic-skip-backward' that uses backward movement to keep