;;; the specified name. (:INIT-WRAPPER is set to COLD-INIT-FORMS
;;; in type system definitions so that caches will be created
;;; before top level forms run.)
+(defvar *cache-vector-symbols* nil)
+
+(defun drop-all-hash-caches ()
+ (dolist (name *cache-vector-symbols*)
+ (set name nil)))
+
(defmacro define-hash-cache (name args &key hash-function hash-bits default
(init-wrapper 'progn)
(values 1))
- (let* ((var-name (symbolicate "*" name "-CACHE-VECTOR*"))
+ (let* ((var-name (symbolicate "**" name "-CACHE-VECTOR**"))
(probes-name (when *profile-hash-cache*
- (symbolicate "*" name "-CACHE-PROBES*")))
+ (symbolicate "**" name "-CACHE-PROBES**")))
(misses-name (when *profile-hash-cache*
- (symbolicate "*" name "-CACHE-MISSES*")))
+ (symbolicate "**" name "-CACHE-MISSES**")))
(nargs (length args))
(size (ash 1 hash-bits))
(default-values (if (and (consp default) (eq (car default) 'values))
`(defun ,fun-name ,(arg-vars)
,@(when *profile-hash-cache*
`((incf ,probes-name)))
- (let* ((,n-index (,hash-function ,@(arg-vars)))
- (,n-cache ,var-name)
- (,args-and-values (svref ,n-cache ,n-index)))
- (cond ((and ,args-and-values
- ,@(tests))
- (values ,@(values-refs)))
- (t
+ (flet ((miss ()
,@(when *profile-hash-cache*
`((incf ,misses-name)))
- ,default))))))
+ (return-from ,fun-name ,default)))
+ (let* ((,n-index (,hash-function ,@(arg-vars)))
+ (,n-cache (or ,var-name (miss)))
+ (,args-and-values (svref ,n-cache ,n-index)))
+ (cond ((and (not (eql 0 ,args-and-values))
+ ,@(tests))
+ (values ,@(values-refs)))
+ (t
+ (miss))))))))
(let ((fun-name (symbolicate name "-CACHE-ENTER")))
(inlines fun-name)
(forms
`(defun ,fun-name (,@(arg-vars) ,@(values-names))
(let ((,n-index (,hash-function ,@(arg-vars)))
- (,n-cache ,var-name)
+ (,n-cache (or ,var-name
+ (setq ,var-name (make-array ,size :initial-element 0))))
(,args-and-values (make-array ,args-and-values-size)))
,@(sets)
(setf (svref ,n-cache ,n-index) ,args-and-values))
(let ((fun-name (symbolicate name "-CACHE-CLEAR")))
(forms
`(defun ,fun-name ()
- (fill ,var-name nil)))
- (forms `(,fun-name)))
+ (setq ,var-name nil))))
- (inits `(unless (boundp ',var-name)
- (setq ,var-name (make-array ,size :initial-element nil))))
+ ;; Needed for cold init!
+ (inits `(setq ,var-name nil))
#!+sb-show (inits `(setq *hash-caches-initialized-p* t))
`(progn
- (defvar ,var-name)
+ (pushnew ',var-name *cache-vector-symbols*)
+ (defglobal ,var-name nil)
,@(when *profile-hash-cache*
- `((defvar ,probes-name)
- (defvar ,misses-name)))
- (declaim (type (simple-vector ,size) ,var-name))
+ `((defglobal ,probes-name 0)
+ (defglobal ,misses-name 0)))
+ (declaim (type (or null (simple-vector ,size)) ,var-name))
#!-sb-fluid (declaim (inline ,@(inlines)))
(,init-wrapper ,@(inits))
,@(forms)
(let ((*gc-inhibit* t))
(let ((old-usage (dynamic-usage))
(new-usage 0))
- (unsafe-clear-roots)
+ (unsafe-clear-roots gen)
(gc-stop-the-world)
(let ((start-time (get-internal-run-time)))
(collect-garbage gen)
(define-alien-routine scrub-control-stack sb!alien:void)
-(defun unsafe-clear-roots ()
+(defun unsafe-clear-roots (gen)
;; KLUDGE: Do things in an attempt to get rid of extra roots. Unsafe
;; as having these cons more then we have space left leads to huge
;; badness.
;; Power cache of the bignum printer: drops overly large bignums and
;; removes duplicate entries.
(scrub-power-cache)
- ;; FIXME: CTYPE-OF-CACHE-CLEAR isn't thread-safe.
- #!-sb-thread
- (ctype-of-cache-clear))
-
+ ;; Clear caches depending on the generation being collected.
+ #!+gencgc
+ (cond ((eql 0 gen))
+ ((eql 1 gen)
+ (ctype-of-cache-clear))
+ (t
+ (drop-all-hash-caches)))
+ #!-gencgc
+ (drop-all-hash-caches))
\f
;;;; auxiliary functions
;;; Clear memoization of all type system operations that can be
;;; altered by type definition/redefinition.
;;;
-;;; FIXME: This should be autogenerated.
(defun clear-type-caches ()
- (declare (special *type-system-initialized*))
- (when *type-system-initialized*
- (dolist (sym '(values-specifier-type-cache-clear
- values-type-union-cache-clear
- type-union2-cache-clear
- values-subtypep-cache-clear
- csubtypep-cache-clear
- type-intersection2-cache-clear
- values-type-intersection-cache-clear
- type=-cache-clear))
- (funcall (the function (symbol-function sym)))))
+ ;; FIXME: We would like to differentiate between different cache
+ ;; kinds, but at the moment all our caches pretty much are type
+ ;; caches.
+ (drop-all-hash-caches)
(values))
;;; This is like TYPE-OF, only we return a CTYPE structure instead of