1.0.18.16: many STYLE-WARNING changes.
[sbcl.git] / src / code / gc.lisp
index c0c7b02..e6abbb1 100644 (file)
         ;; See comment in interr.lisp
         *heap-exhausted-error-condition* (make-condition 'heap-exhausted-error)))
 
-(declaim (ftype (function () unsigned-byte) get-bytes-consed))
+(declaim (ftype (sfunction () unsigned-byte) get-bytes-consed))
 (defun get-bytes-consed ()
   #!+sb-doc
   "Return the number of bytes consed since the program began. Typically
@@ -180,9 +180,25 @@ run in any thread.")
 (defvar *already-in-gc*
   (sb!thread:make-mutex :name "GC lock") "ID of thread running SUB-GC")
 
+;;; A unique GC id. This is supplied for code that needs to detect
+;;; whether a GC has happened since some earlier point in time. For
+;;; example:
+;;;
+;;;   (let ((epoch *gc-epoch*))
+;;;      ...
+;;;      (unless (eql epoch *gc-epoch)
+;;;        ....))
+;;;
+;;; This isn't just a fixnum counter since then we'd have theoretical
+;;; problems when exactly 2^29 GCs happen between epoch
+;;; comparisons. Unlikely, but the cost of using a cons instead is too
+;;; small to measure. -- JES, 2007-09-30
+(declaim (type cons *gc-epoch*))
+(defvar *gc-epoch* (cons nil nil))
+
 (defun sub-gc (&key (gen 0))
   (unless (eq sb!thread:*current-thread*
-              (sb!thread::mutex-value *already-in-gc*))
+              (sb!thread:mutex-value *already-in-gc*))
     ;; With gencgc, unless *GC-PENDING* every allocation in this
     ;; function triggers another gc, potentially exceeding maximum
     ;; interrupt nesting. If *GC-INHIBIT* is not true, however,
@@ -202,6 +218,7 @@ run in any thread.")
                  (gc-stop-the-world)
                  (let ((start-time (get-internal-run-time)))
                    (collect-garbage gen)
+                   (setf *gc-epoch* (cons nil nil))
                    (incf *gc-run-time*
                          (- (get-internal-run-time) start-time)))
                  (setf *gc-pending* nil
@@ -231,11 +248,7 @@ run in any thread.")
            ;; for finalizers and after-gc hooks.
            (when (sb!thread:thread-alive-p sb!thread:*current-thread*)
              (run-pending-finalizers)
-             (dolist (hook *after-gc-hooks*)
-               (handler-case
-                   (funcall hook)
-                 (serious-condition (c)
-                   (warn "Error calling after-GC hook ~S:~% ~A" hook c)))))))))
+             (call-hooks "after-GC" *after-gc-hooks* :on-error :warn))))))
 
 ;;; This is the user-advertised garbage collection function.
 (defun gc (&key (gen 0) (full nil) &allow-other-keys)
@@ -252,6 +265,9 @@ run in any thread.")
   ;; as having these cons more then we have space left leads to huge
   ;; badness.
   (scrub-control-stack)
+  ;; 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))