Function: ad-get-cache-definition
ad-get-cache-definition is a byte-compiled function defined in
advice.el.gz.
Signature
(ad-get-cache-definition FUNCTION)
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/advice.el.gz
;; @@ Caching:
;; ===========
;; Generating an advised definition of a function is moderately expensive,
;; hence, it makes sense to cache it so we can reuse it in appropriate
;; circumstances. Of course, it only makes sense to reuse a cached
;; definition if the current advice and function definition state is the
;; same as it was at the time when the cached definition was generated.
;; For that purpose we associate every cache with an id so we can verify
;; if it is still valid at a certain point in time. This id mechanism
;; makes it possible to preactivate advised functions, write the compiled
;; advised definitions to a file and reuse them during the actual
;; activation without having to risk that the resulting definition will be
;; incorrect, well, almost.
;;
;; A cache id is a list with six elements:
;; 1) the list of names of enabled before advices
;; 2) the list of names of enabled around advices
;; 3) the list of names of enabled after advices
;; 4) the type of the original function (macro, subr, etc.)
;; 5) the arglist of the original definition (or t if it was equal to the
;; arglist of the cached definition)
;; 6) t if the interactive form of the original definition was equal to the
;; interactive form of the cached definition
;;
;; Here's how a cache can get invalidated or be incorrect:
;; A) a piece of advice used in the cache gets redefined
;; B) the current list of enabled advices is different from the ones used
;; for the cache
;; C) the type of the original function changed, e.g., a function became a
;; macro, or a subr became a function
;; D) the arglist of the original function changed
;; E) the interactive form of the original function changed
;; F) a piece of advice used in the cache got redefined before the
;; defadvice with the cached definition got loaded: This is a PROBLEM!
;;
;; Cases A and B are the normal ones. A is taken care of by `ad-add-advice'
;; which clears the cache in such a case, B is easily checked during
;; verification at activation time.
;;
;; Cases C, D and E have to be considered if one is slightly paranoid, i.e.,
;; if one considers the case that the original function could be different
;; from the one available at caching time (e.g., for forward advice of
;; functions that get redefined by some packages - such as `eval-region' gets
;; redefined by edebug). All these cases can be easily checked during
;; verification. Element 4 of the id lets one check case C, element 5 takes
;; care of case D (using t in the equality case saves some space, because the
;; arglist can be recovered at validation time from the cached definition),
;; and element 6 takes care of case E which is only a problem if the original
;; was actually a function whose interactive form was not overridden by a
;; piece of advice.
;;
;; Case F is the only one which will lead to an incorrect advised function.
;; There is no way to avoid this without storing the complete advice definition
;; in the cache-id which is not feasible.
;;
;; The cache-id of a typical advised function with one piece of advice and
;; no arglist redefinition takes 7 conses which is a small price to pay for
;; the added efficiency. The validation itself is also pretty cheap, certainly
;; a lot cheaper than reconstructing an advised definition.
(defsubst ad-get-cache-definition (function)
(car (ad-get-advice-info-field function 'cache)))