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)
(push-mark))
(c-self-bind-state-cache ; We must not share with other users of c-state-cache.
(c-save-buffer-state
(beginning-of-defun-function end-of-defun-function
(beginning-of-defun-function
end-of-defun-function
(start (point))
(paren-state (copy-tree (c-parse-state))) ; This must not share list
; structure with other users of c-state-cache.
(paren-state (c-parse-state))
(orig-point-min (point-min)) (orig-point-max (point-max))
lim ; Position of { which has been widened to.
where pos case-fold-search)
@ -1656,7 +1657,7 @@ defun."
(goto-char pos)))
(c-keep-region-active)
(= arg 0)))))
(= arg 0))))))
(defun c-forward-to-nth-EOF-} (n where)
;; 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)
(push-mark))
(c-self-bind-state-cache ; c-state-cache's list structure must not be shared
; with other users.
(c-save-buffer-state
(beginning-of-defun-function end-of-defun-function
(beginning-of-defun-function
end-of-defun-function
(start (point))
(paren-state (copy-tree (c-parse-state))) ; This must not share list
; structure with other users of c-state-cache.
(paren-state (c-parse-state))
(orig-point-min (point-min)) (orig-point-max (point-max))
lim
where pos case-fold-search)
@ -1777,7 +1780,7 @@ the open-parenthesis that starts a defun; see `beginning-of-defun'."
(goto-char pos))))
(c-keep-region-active)
(= arg 0))))
(= arg 0)))))
(defun c-defun-name ()
"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-properties 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.
@ -1397,6 +1398,26 @@ been put there by c-put-char-property. POINT remains unchanged."
(save-restriction
(widen)
(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

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)))
(unless (setq safe-pos (car-safe safe-pos-list))
(setq safe-pos (max (or (c-safe-position
(point) (or c-state-cache
(c-parse-state)))
(point) (c-parse-state))
0)
(point-min))
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
comment at the start of cc-engine.el for more info."
(c-self-bind-state-cache
(let ((start (point))
state-2
;; 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
;; the future.
(/= (point) start)))
(/= (point) start))))
;; The following is an alternative implementation of
;; `c-syntactic-skip-backward' that uses backward movement to keep