0.6.11.13:
[sbcl.git] / src / code / gc.lisp
index 7921d48..020eab8 100644 (file)
@@ -10,9 +10,6 @@
 ;;;; files for more information.
 
 (in-package "SB!KERNEL")
-
-(file-comment
-  "$Header$")
 \f
 ;;;; DYNAMIC-USAGE and friends
 
        (defun ,lisp-fun ()
         (sb!alien:extern-alien ,c-var-name (sb!alien:unsigned 32))))))
 
-(def-c-var-frob sb!vm:control-stack-start          "control_stack")
-#!+x86 (def-c-var-frob control-stack-end            "control_stack_end")
-(def-c-var-frob sb!vm:binding-stack-start          "binding_stack")
-(def-c-var-frob sb!vm:current-dynamic-space-start "current_dynamic_space")
-
 #!-sb-fluid (declaim (inline dynamic-usage))
-#!-(or cgc gencgc)
-(defun dynamic-usage ()
-  (the (unsigned-byte 32)
-       (- (sb!sys:sap-int (sb!c::dynamic-space-free-pointer))
-         (sb!vm:current-dynamic-space-start))))
-#!+(or cgc gencgc)
 (def-c-var-frob dynamic-usage "bytes_allocated")
 
 (defun static-space-usage ()
   (- (* sb!vm:*static-space-free-pointer* sb!vm:word-bytes)
-     sb!vm:*static-space-start*))
+     sb!vm:static-space-start))
 
 (defun read-only-space-usage ()
   (- (* sb!vm::*read-only-space-free-pointer* sb!vm:word-bytes)
-     sb!vm:*read-only-space-start*))
+     sb!vm:read-only-space-start))
 
 (defun control-stack-usage ()
   #!-x86 (- (sb!sys:sap-int (sb!c::control-stack-pointer-sap))
-           (control-stack-start))
-  #!+x86 (- (control-stack-end)
+            sb!vm:control-stack-start)
+  #!+x86 (- sb!vm:control-stack-end
            (sb!sys:sap-int (sb!c::control-stack-pointer-sap))))
 
 (defun binding-stack-usage ()
   (- (sb!sys:sap-int (sb!c::binding-stack-pointer-sap))
-     (sb!vm:binding-stack-start)))
+     sb!vm:binding-stack-start))
 \f
 ;;;; ROOM
 
   #!+sb-doc
   "The total CPU time spent doing garbage collection (as reported by
    GET-INTERNAL-RUN-TIME.)")
-
 (declaim (type index *gc-run-time*))
 
+;;; a limit to help catch programs which allocate too much memory,
+;;; since a hard heap overflow is so hard to recover from. 
+(declaim (type (or unsigned-byte null) *soft-heap-limit*))
+(defvar *soft-heap-limit* nil)
+
 ;;; Internal trigger. When the dynamic usage increases beyond this
 ;;; amount, the system notes that a garbage collection needs to occur by
 ;;; setting *NEED-TO-COLLECT-GARBAGE* to T. It starts out as NIL meaning
 (sb!alien:def-alien-routine collect-garbage sb!c-call:int
   #!+gencgc (last-gen sb!c-call:int))
 
-#!-ibmrt
 (sb!alien:def-alien-routine set-auto-gc-trigger sb!c-call:void
   (dynamic-usage sb!c-call:unsigned-long))
 
-#!+ibmrt
-(defun set-auto-gc-trigger (bytes)
-  (let ((words (ash (+ (sb!vm:current-dynamic-space-start) bytes) -2)))
-    (unless (and (fixnump words) (plusp words))
-      (clear-auto-gc-trigger)
-      (warn "attempt to set GC trigger to something bogus: ~S" bytes))
-    (setf %rt::*internal-gc-trigger* words)))
-
-#!-ibmrt
 (sb!alien:def-alien-routine clear-auto-gc-trigger sb!c-call:void)
 
-#!+ibmrt
-(defun clear-auto-gc-trigger ()
-  (setf %rt::*internal-gc-trigger* -1))
-
 ;;; This variable contains the function that does the real GC. This is
 ;;; for low-level GC experimentation. Do not touch it if you do not
 ;;; know what you are doing.
     (/show0 "not *ALREADY-MAYBE-GCING*")
     (let* ((*already-maybe-gcing* t)
           (start-time (get-internal-run-time))
-          (pre-gc-dyn-usage (dynamic-usage)))
+          (pre-gc-dyn-usage (dynamic-usage))
+          ;; Currently we only check *SOFT-HEAP-LIMIT* at GC time,
+          ;; not for every allocation. That makes it cheap to do,
+          ;; even if it is a little ugly.
+          (soft-heap-limit-exceeded? (and *soft-heap-limit*
+                                          (> pre-gc-dyn-usage
+                                             *soft-heap-limit*)))
+          (*soft-heap-limit* (if soft-heap-limit-exceeded?
+                                 (+ pre-gc-dyn-usage
+                                    *bytes-consed-between-gcs*)
+                                 *soft-heap-limit*)))
+      (when soft-heap-limit-exceeded?
+       (cerror "Continue with GC."
+               "soft heap limit exceeded (temporary new limit=~D)"
+               *soft-heap-limit*))
       (unless (integerp (symbol-value '*bytes-consed-between-gcs*))
        ;; The noise w/ symbol-value above is to keep the compiler
        ;; from optimizing the test away because of the type declaim
            (/show0 "back from FUNCALL to *INTERNAL-GC*")
            (let* ((post-gc-dyn-usage (dynamic-usage))
                   (bytes-freed (- pre-gc-dyn-usage post-gc-dyn-usage)))
+             (/show0 "got (DYNAMIC-USAGE) and BYTES-FREED")
              (when *last-bytes-in-use*
+               (/show0 "doing *LAST-BYTES-IN-USE* thing")
                (incf *total-bytes-consed*
                      (- pre-gc-dyn-usage *last-bytes-in-use*))
+               (/show0 "setting *LAST-BYTES-IN-USE*")
                (setq *last-bytes-in-use* post-gc-dyn-usage))
+             (/show0 "clearing *NEED-TO-COLLECT-GARBAGE*")
              (setf *need-to-collect-garbage* nil)
+             (/show0 "calculating NEW-GC-TRIGGER")
              (let ((new-gc-trigger (+ post-gc-dyn-usage
                                       *bytes-consed-between-gcs*)))
+               (/show0 "setting *GC-TRIGGER*")
                (setf *gc-trigger* new-gc-trigger))
+             (/show0 "calling SET-AUTO-GC-TRIGGER")
              (set-auto-gc-trigger *gc-trigger*)
              (dolist (hook *after-gc-hooks*)
                (/show0 "doing a hook from *AFTER-GC--HOOKS*")
-               ;; FIXME: This hook should be called with the
-               ;; same kind of information as *GC-NOTIFY-AFTER*.
-               ;; In particular, it would be nice for the
-               ;; hook function to be able to adjust *GC-TRIGGER*
-               ;; intelligently to e.g. 108% of total memory usage.
+               ;; FIXME: This hook should be called with the same
+               ;; kind of information as *GC-NOTIFY-AFTER*. In
+               ;; particular, it would be nice for the hook function
+               ;; to be able to adjust *GC-TRIGGER* intelligently to
+               ;; e.g. 108% of total memory usage.
                (carefully-funcall hook))
              (when *gc-notify-stream*
                (/show0 "doing the *GC-NOTIFY-AFTER* thing")
       (incf *gc-run-time* (- (get-internal-run-time)
                             start-time))))
   ;; FIXME: should probably return (VALUES), here and in RETURN-FROM
-  (/show "returning from tail of SUB-GC")
+  (/show0 "returning from tail of SUB-GC")
   nil)
 
 ;;; This routine is called by the allocation miscops to decide whether