X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Ftoplevel.lisp;h=f4baf40f061c756b75d8f4f5f8698dc885c8f383;hb=6e7ae26173b40d635b94e81bc73f5c06d550de32;hp=092a0cb30735b4f3c1b6c056578b6a08fc3faaf5;hpb=f0d511130027c6878f08d619ccc92ef588d81223;p=sbcl.git diff --git a/src/code/toplevel.lisp b/src/code/toplevel.lisp index 092a0cb..f4baf40 100644 --- a/src/code/toplevel.lisp +++ b/src/code/toplevel.lisp @@ -65,7 +65,8 @@ (/show0 "back from INFINITE-ERROR-PROTECTOR") (let ((*current-error-depth* (1+ *current-error-depth*))) (/show0 "in INFINITE-ERROR-PROTECT, incremented error depth") - #+sb-show (sb-debug:backtrace) + ;; arbitrary truncation + #!+sb-show (sb!debug:backtrace 8) ,@forms))) ;;; a helper function for INFINITE-ERROR-PROTECT @@ -152,75 +153,89 @@ ;;; Zero the unused portion of the control stack so that old objects ;;; are not kept alive because of uninitialized stack variables. -;;; -;;; FIXME: Why do we need to do this instead of just letting GC read -;;; the stack pointer and avoid messing with the unused portion of -;;; the control stack? (Is this a multithreading thing where there's -;;; one control stack and stack pointer per thread, and it might not -;;; be easy to tell what a thread's stack pointer value is when -;;; looking in from another thread?) + +;;; "To summarize the problem, since not all allocated stack frame +;;; slots are guaranteed to be written by the time you call an another +;;; function or GC, there may be garbage pointers retained in your +;;; dead stack locations. The stack scrubbing only affects the part +;;; of the stack from the SP to the end of the allocated stack." +;;; - ram, on cmucl-imp, Tue, 25 Sep 2001 + +;;; So, as an (admittedly lame) workaround, from time to time we call +;;; scrub-control-stack to zero out all the unused portion. This is +;;; supposed to happen when the stack is mostly empty, so that we have +;;; a chance of clearing more of it: callers are currently (2002.07.18) +;;; REPL and SUB-GC + (defun scrub-control-stack () (declare (optimize (speed 3) (safety 0)) (values (unsigned-byte 20))) ; FIXME: DECLARE VALUES? #!-stack-grows-downward-not-upward - (labels - ((scrub (ptr offset count) - (declare (type system-area-pointer ptr) - (type (unsigned-byte 16) offset) - (type (unsigned-byte 20) count) - (values (unsigned-byte 20))) - (cond ((= offset bytes-per-scrub-unit) - (look (sap+ ptr bytes-per-scrub-unit) 0 count)) - (t - (setf (sap-ref-32 ptr offset) 0) - (scrub ptr (+ offset sb!vm:n-word-bytes) count)))) - (look (ptr offset count) - (declare (type system-area-pointer ptr) - (type (unsigned-byte 16) offset) - (type (unsigned-byte 20) count) - (values (unsigned-byte 20))) - (cond ((= offset bytes-per-scrub-unit) - count) - ((zerop (sap-ref-32 ptr offset)) - (look ptr (+ offset sb!vm:n-word-bytes) count)) - (t - (scrub ptr offset (+ count sb!vm:n-word-bytes)))))) - (let* ((csp (sap-int (sb!c::control-stack-pointer-sap))) - (initial-offset (logand csp (1- bytes-per-scrub-unit)))) + (let* ((csp (sap-int (sb!c::control-stack-pointer-sap))) + (initial-offset (logand csp (1- bytes-per-scrub-unit))) + (end-of-stack + (- sb!vm:control-stack-end sb!c:*backend-page-size*))) + (labels + ((scrub (ptr offset count) + (declare (type system-area-pointer ptr) + (type (unsigned-byte 16) offset) + (type (unsigned-byte 20) count) + (values (unsigned-byte 20))) + (cond ((>= (sap-int ptr) end-of-stack) 0) + ((= offset bytes-per-scrub-unit) + (look (sap+ ptr bytes-per-scrub-unit) 0 count)) + (t + (setf (sap-ref-32 ptr offset) 0) + (scrub ptr (+ offset sb!vm:n-word-bytes) count)))) + (look (ptr offset count) + (declare (type system-area-pointer ptr) + (type (unsigned-byte 16) offset) + (type (unsigned-byte 20) count) + (values (unsigned-byte 20))) + (cond ((>= (sap-int ptr) end-of-stack) 0) + ((= offset bytes-per-scrub-unit) + count) + ((zerop (sap-ref-32 ptr offset)) + (look ptr (+ offset sb!vm:n-word-bytes) count)) + (t + (scrub ptr offset (+ count sb!vm:n-word-bytes)))))) (declare (type (unsigned-byte 32) csp)) (scrub (int-sap (- csp initial-offset)) (* (floor initial-offset sb!vm:n-word-bytes) sb!vm:n-word-bytes) 0))) #!+stack-grows-downward-not-upward - (labels - ((scrub (ptr offset count) - (declare (type system-area-pointer ptr) - (type (unsigned-byte 16) offset) - (type (unsigned-byte 20) count) - (values (unsigned-byte 20))) - (let ((loc (int-sap (- (sap-int ptr) (+ offset sb!vm:n-word-bytes))))) - (cond ((= offset bytes-per-scrub-unit) - (look (int-sap (- (sap-int ptr) bytes-per-scrub-unit)) - 0 count)) - (t ;; need to fix bug in %SET-STACK-REF - (setf (sap-ref-32 loc 0) 0) - (scrub ptr (+ offset sb!vm:n-word-bytes) count))))) - (look (ptr offset count) - (declare (type system-area-pointer ptr) - (type (unsigned-byte 16) offset) - (type (unsigned-byte 20) count) - (values (unsigned-byte 20))) - (let ((loc (int-sap (- (sap-int ptr) offset)))) - (cond ((= offset bytes-per-scrub-unit) - count) - ((zerop (sb!kernel::get-lisp-obj-address (stack-ref loc 0))) - (look ptr (+ offset sb!vm:n-word-bytes) count)) - (t - (scrub ptr offset (+ count sb!vm:n-word-bytes))))))) - (let* ((csp (sap-int (sb!c::control-stack-pointer-sap))) - (initial-offset (logand csp (1- bytes-per-scrub-unit)))) + (let* ((csp (sap-int (sb!c::control-stack-pointer-sap))) + (end-of-stack (+ sb!vm:control-stack-start sb!c:*backend-page-size*)) + (initial-offset (logand csp (1- bytes-per-scrub-unit)))) + (labels + ((scrub (ptr offset count) + (declare (type system-area-pointer ptr) + (type (unsigned-byte 16) offset) + (type (unsigned-byte 20) count) + (values (unsigned-byte 20))) + (let ((loc (int-sap (- (sap-int ptr) (+ offset sb!vm:n-word-bytes))))) + (cond ((< (sap-int loc) end-of-stack) 0) + ((= offset bytes-per-scrub-unit) + (look (int-sap (- (sap-int ptr) bytes-per-scrub-unit)) + 0 count)) + (t ;; need to fix bug in %SET-STACK-REF + (setf (sap-ref-32 loc 0) 0) + (scrub ptr (+ offset sb!vm:n-word-bytes) count))))) + (look (ptr offset count) + (declare (type system-area-pointer ptr) + (type (unsigned-byte 16) offset) + (type (unsigned-byte 20) count) + (values (unsigned-byte 20))) + (let ((loc (int-sap (- (sap-int ptr) offset)))) + (cond ((< (sap-int loc) end-of-stack) 0) + ((= offset bytes-per-scrub-unit) + count) + ((zerop (sb!kernel::get-lisp-obj-address (stack-ref loc 0))) + (look ptr (+ offset sb!vm:n-word-bytes) count)) + (t + (scrub ptr offset (+ count sb!vm:n-word-bytes))))))) (declare (type (unsigned-byte 32) csp)) (scrub (int-sap (+ csp initial-offset)) (* (floor initial-offset sb!vm:n-word-bytes) sb!vm:n-word-bytes) @@ -245,7 +260,10 @@ "Evaluate FORM, returning whatever it returns and adjusting ***, **, *, +++, ++, +, ///, //, /, and -." (setf - form) - (let ((results (multiple-value-list (eval form)))) + (let ((results + (multiple-value-list + (eval-in-lexenv form + (make-null-interactive-lexenv))))) (setf /// // // / / results @@ -482,9 +500,13 @@ ;; get you out to here. (with-simple-restart (abort - "Reduce debugger level (leaving debugger, returning to toplevel).") + "~@") (catch 'toplevel-catcher #!-sunos (sb!unix:unix-sigsetmask 0) ; FIXME: What is this for? + ;; in the event of a control-stack-exhausted-error, we should + ;; have unwound enough stack by the time we get here that this + ;; is now possible + (sb!kernel::protect-control-stack-guard-page 1) (repl noprint) (critically-unreachable "after REPL"))))))) @@ -492,10 +514,7 @@ (/show0 "entering REPL") (let ((eof-marker (cons :eof nil))) (loop - ;; FIXME: It seems bad to have GC behavior depend on scrubbing the - ;; control stack before each interactive command. Isn't there some - ;; way we can convince the GC to just ignore dead areas of the - ;; control stack, so that we don't need to rely on this half-measure? + ;; see comment preceding definition of SCRUB-CONTROL-STACK (scrub-control-stack) (unless noprint (fresh-line)