diff options
| author | Stefan Monnier | 2013-09-04 23:05:44 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2013-09-04 23:05:44 -0400 |
| commit | 4c528aabaa750d9a4e739dde482b307b734dcd62 (patch) | |
| tree | c541b14775eb8ee37f092de44cdcf189da4c85ae | |
| parent | a7e43722c705f2b124fe7fa6a41cac76d0fe5b3a (diff) | |
| download | emacs-4c528aabaa750d9a4e739dde482b307b734dcd62.tar.gz emacs-4c528aabaa750d9a4e739dde482b307b734dcd62.zip | |
* lisp/emacs-lisp/cconv.el: Use `car-safe' rather than `car' to access
a "ref-cell", since it gets better optimized.
Fixes: debbugs:14883
| -rw-r--r-- | lisp/ChangeLog | 5 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cconv.el | 20 | ||||
| -rw-r--r-- | lisp/vc/vc-dispatcher.el | 3 |
3 files changed, 16 insertions, 12 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 46c19995678..9633fc29c30 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2013-09-05 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * emacs-lisp/cconv.el: Use `car-safe' rather than `car' to access | ||
| 4 | a "ref-cell", since it gets better optimized (bug#14883). | ||
| 5 | |||
| 1 | 2013-09-05 Glenn Morris <rgm@gnu.org> | 6 | 2013-09-05 Glenn Morris <rgm@gnu.org> |
| 2 | 7 | ||
| 3 | * progmodes/cc-awk.el (c-forward-sws): Declare. | 8 | * progmodes/cc-awk.el (c-forward-sws): Declare. |
diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el index f688bff6f85..c655c2fff84 100644 --- a/lisp/emacs-lisp/cconv.el +++ b/lisp/emacs-lisp/cconv.el | |||
| @@ -55,7 +55,7 @@ | |||
| 55 | ;; | 55 | ;; |
| 56 | ;; If a variable is mutated (updated by setq), and it is used in a closure | 56 | ;; If a variable is mutated (updated by setq), and it is used in a closure |
| 57 | ;; we wrap its definition with list: (list val) and we also replace | 57 | ;; we wrap its definition with list: (list val) and we also replace |
| 58 | ;; var => (car var) wherever this variable is used, and also | 58 | ;; var => (car-safe var) wherever this variable is used, and also |
| 59 | ;; (setq var value) => (setcar var value) where it is updated. | 59 | ;; (setq var value) => (setcar var value) where it is updated. |
| 60 | ;; | 60 | ;; |
| 61 | ;; If defun argument is closure mutable, we letbind it and wrap it's | 61 | ;; If defun argument is closure mutable, we letbind it and wrap it's |
| @@ -211,9 +211,9 @@ Returns a form where all lambdas don't have any free variables." | |||
| 211 | ;; If `fv' is a variable that's wrapped in a cons-cell, | 211 | ;; If `fv' is a variable that's wrapped in a cons-cell, |
| 212 | ;; we want to put the cons-cell itself in the closure, | 212 | ;; we want to put the cons-cell itself in the closure, |
| 213 | ;; rather than just a copy of its current content. | 213 | ;; rather than just a copy of its current content. |
| 214 | (`(car ,iexp . ,_) | 214 | (`(car-safe ,iexp . ,_) |
| 215 | (push iexp envector) | 215 | (push iexp envector) |
| 216 | (push `(,fv . (car (internal-get-closed-var ,i))) new-env)) | 216 | (push `(,fv . (car-safe (internal-get-closed-var ,i))) new-env)) |
| 217 | (_ | 217 | (_ |
| 218 | (push exp envector) | 218 | (push exp envector) |
| 219 | (push `(,fv . (internal-get-closed-var ,i)) new-env)))) | 219 | (push `(,fv . (internal-get-closed-var ,i)) new-env)))) |
| @@ -224,7 +224,7 @@ Returns a form where all lambdas don't have any free variables." | |||
| 224 | (dolist (arg args) | 224 | (dolist (arg args) |
| 225 | (if (not (member (cons (list arg) parentform) cconv-captured+mutated)) | 225 | (if (not (member (cons (list arg) parentform) cconv-captured+mutated)) |
| 226 | (if (assq arg new-env) (push `(,arg) new-env)) | 226 | (if (assq arg new-env) (push `(,arg) new-env)) |
| 227 | (push `(,arg . (car ,arg)) new-env) | 227 | (push `(,arg . (car-safe ,arg)) new-env) |
| 228 | (push `(,arg (list ,arg)) letbind))) | 228 | (push `(,arg (list ,arg)) letbind))) |
| 229 | 229 | ||
| 230 | (setq body-new (mapcar (lambda (form) | 230 | (setq body-new (mapcar (lambda (form) |
| @@ -254,7 +254,7 @@ ENV is a lexical environment mapping variables to the expression | |||
| 254 | used to get its value. This is used for variables that are copied into | 254 | used to get its value. This is used for variables that are copied into |
| 255 | closures, moved into cons cells, ... | 255 | closures, moved into cons cells, ... |
| 256 | ENV is a list where each entry takes the shape either: | 256 | ENV is a list where each entry takes the shape either: |
| 257 | (VAR . (car EXP)): VAR has been moved into the car of a cons-cell, and EXP | 257 | (VAR . (car-safe EXP)): VAR has been moved into the car of a cons-cell, and EXP |
| 258 | is an expression that evaluates to this cons-cell. | 258 | is an expression that evaluates to this cons-cell. |
| 259 | (VAR . (internal-get-closed-var N)): VAR has been copied into the closure | 259 | (VAR . (internal-get-closed-var N)): VAR has been copied into the closure |
| 260 | environment's Nth slot. | 260 | environment's Nth slot. |
| @@ -320,9 +320,9 @@ places where they originally did not directly appear." | |||
| 320 | (push `(,var . (apply-partially ,var . ,fvs)) new-env) | 320 | (push `(,var . (apply-partially ,var . ,fvs)) new-env) |
| 321 | (dolist (fv fvs) | 321 | (dolist (fv fvs) |
| 322 | (cl-pushnew fv new-extend) | 322 | (cl-pushnew fv new-extend) |
| 323 | (if (and (eq 'car (car-safe (cdr (assq fv env)))) | 323 | (if (and (eq 'car-safe (car-safe (cdr (assq fv env)))) |
| 324 | (not (memq fv funargs))) | 324 | (not (memq fv funargs))) |
| 325 | (push `(,fv . (car ,fv)) funcbody-env))) | 325 | (push `(,fv . (car-safe ,fv)) funcbody-env))) |
| 326 | `(function (lambda ,funcvars . | 326 | `(function (lambda ,funcvars . |
| 327 | ,(mapcar (lambda (form) | 327 | ,(mapcar (lambda (form) |
| 328 | (cconv-convert | 328 | (cconv-convert |
| @@ -332,7 +332,7 @@ places where they originally did not directly appear." | |||
| 332 | ;; Check if it needs to be turned into a "ref-cell". | 332 | ;; Check if it needs to be turned into a "ref-cell". |
| 333 | ((member (cons binder form) cconv-captured+mutated) | 333 | ((member (cons binder form) cconv-captured+mutated) |
| 334 | ;; Declared variable is mutated and captured. | 334 | ;; Declared variable is mutated and captured. |
| 335 | (push `(,var . (car ,var)) new-env) | 335 | (push `(,var . (car-safe ,var)) new-env) |
| 336 | `(list ,(cconv-convert value env extend))) | 336 | `(list ,(cconv-convert value env extend))) |
| 337 | 337 | ||
| 338 | ;; Normal default case. | 338 | ;; Normal default case. |
| @@ -448,7 +448,7 @@ places where they originally did not directly appear." | |||
| 448 | (value (cconv-convert (pop forms) env extend))) | 448 | (value (cconv-convert (pop forms) env extend))) |
| 449 | (push (pcase sym-new | 449 | (push (pcase sym-new |
| 450 | ((pred symbolp) `(setq ,sym-new ,value)) | 450 | ((pred symbolp) `(setq ,sym-new ,value)) |
| 451 | (`(car ,iexp) `(setcar ,iexp ,value)) | 451 | (`(car-safe ,iexp) `(setcar ,iexp ,value)) |
| 452 | ;; This "should never happen", but for variables which are | 452 | ;; This "should never happen", but for variables which are |
| 453 | ;; mutated+captured+unused, we may end up trying to `setq' | 453 | ;; mutated+captured+unused, we may end up trying to `setq' |
| 454 | ;; on a closed-over variable, so just drop the setq. | 454 | ;; on a closed-over variable, so just drop the setq. |
| @@ -472,7 +472,7 @@ places where they originally did not directly appear." | |||
| 472 | ,@(mapcar (lambda (fv) | 472 | ,@(mapcar (lambda (fv) |
| 473 | (let ((exp (or (cdr (assq fv env)) fv))) | 473 | (let ((exp (or (cdr (assq fv env)) fv))) |
| 474 | (pcase exp | 474 | (pcase exp |
| 475 | (`(car ,iexp . ,_) iexp) | 475 | (`(car-safe ,iexp . ,_) iexp) |
| 476 | (_ exp)))) | 476 | (_ exp)))) |
| 477 | fvs) | 477 | fvs) |
| 478 | ,@(mapcar (lambda (arg) | 478 | ,@(mapcar (lambda (arg) |
diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el index 1b8bfa274f8..7888752553e 100644 --- a/lisp/vc/vc-dispatcher.el +++ b/lisp/vc/vc-dispatcher.el | |||
| @@ -224,8 +224,7 @@ Another is that undo information is not kept." | |||
| 224 | "Eval CODE when the current buffer's process is done. | 224 | "Eval CODE when the current buffer's process is done. |
| 225 | If the current buffer has no process, just evaluate CODE. | 225 | If the current buffer has no process, just evaluate CODE. |
| 226 | Else, add CODE to the process' sentinel. | 226 | Else, add CODE to the process' sentinel. |
| 227 | CODE can be either a function of no arguments, or an expression | 227 | CODE should be a function of no arguments." |
| 228 | to evaluate." | ||
| 229 | (let ((proc (get-buffer-process (current-buffer)))) | 228 | (let ((proc (get-buffer-process (current-buffer)))) |
| 230 | (cond | 229 | (cond |
| 231 | ;; If there's no background process, just execute the code. | 230 | ;; If there's no background process, just execute the code. |