From 5919ecc5fee77630855da6aeeabdc7d8cc4f2762 Mon Sep 17 00:00:00 2001 From: Nikodemus Siivola Date: Sun, 21 Dec 2008 09:51:01 +0000 Subject: [PATCH] 1.0.23.60: fix bug 354: XEPs in backtraces, properly this time * Don't terminate the block in MAYBE-TERMINATE-BLOCK even if the node is a call to a function that never returns if it is also the tail end of a XEP -- this allows TCO to deal with the XEP. * More stale bugs: ** 143 -- cannot replicate, interrupt handling has been robustified and partially redesigned since than, so confidence that this is really gone is reasonably high. ** 238 -- has gotten fixed at some point. --- BUGS | 63 ---------------------------------------------- NEWS | 3 +++ src/compiler/ir1opt.lisp | 13 +++++++++- tests/debug.impure.lisp | 10 ++++++++ tests/eval.impure.lisp | 12 +++++++++ version.lisp-expr | 2 +- 6 files changed, 38 insertions(+), 65 deletions(-) diff --git a/BUGS b/BUGS index 9dd8b02..f92cfa8 100644 --- a/BUGS +++ b/BUGS @@ -340,28 +340,6 @@ WORKAROUND: forever, even when it is uninterned and all other references to it are lost. -143: - (reported by Jesse Bouwman 2001-10-24 through the unfortunately - prominent SourceForge web/db bug tracking system, which is - unfortunately not a reliable way to get a timely response from - the SBCL maintainers) - In the course of trying to build a test case for an - application error, I encountered this behavior: - If you start up sbcl, and then lay on CTRL-C for a - minute or two, the lisp process will eventually say: - %PRIMITIVE HALT called; the party is over. - and throw you into the monitor. If I start up lisp, - attach to the process with strace, and then do the same - (abusive) thing, I get instead: - access failure in heap page not marked as write-protected - and the monitor again. I don't know enough to have the - faintest idea of what is going on here. - This is with sbcl 6.12, uname -a reports: - Linux prep 2.2.19 #4 SMP Tue Apr 24 13:59:52 CDT 2001 i686 unknown - I (WHN) have verified that the same thing occurs on sbcl-0.pre7.141 - under OpenBSD 2.9 on my X86 laptop. Do be patient when you try it: - it took more than two minutes (but less than five) for me. - 145: a. ANSI allows types `(COMPLEX ,FOO) to use very hairy values for @@ -648,32 +626,6 @@ WORKAROUND: calls of the form (TYPEP 1 'INTEGER NIL), even though this is just as optimizeable as (TYPEP 1 'INTEGER). -238: "REPL compiler overenthusiasm for CLOS code" - From the REPL, - * (defclass foo () ()) - * (defmethod bar ((x foo) (foo foo)) (call-next-method)) - causes approximately 100 lines of code deletion notes. Some - discussion on this issue happened under the title 'Three "interesting" - bugs in PCL', resulting in a fix for this oververbosity from the - compiler proper; however, the problem persists in the interactor - because the notion of original source is not preserved: for the - compiler, the original source of the above expression is (DEFMETHOD - BAR ((X FOO) (FOO FOO)) (CALL-NEXT-METHOD)), while by the time the - compiler gets its hands on the code needing compilation from the REPL, - it has been macroexpanded several times. - - A symptom of the same underlying problem, reported by Tony Martinez: - * (handler-case - (with-input-from-string (*query-io* " no") - (yes-or-no-p)) - (simple-type-error () 'error)) - ; in: LAMBDA NIL - ; (SB-KERNEL:FLOAT-WAIT) - ; - ; note: deleting unreachable code - ; compilation unit finished - ; printed 1 note - 242: "WRITE-SEQUENCE suboptimality" (observed from clx performance) In sbcl-0.7.13, WRITE-SEQUENCE of a sequence of type @@ -1216,21 +1168,6 @@ WORKAROUND: conditionalization and OAOOMization: refactoring the common parts would be good. -354: XEPs in backtraces - Under default compilation policy - (defun test () - (throw :unknown t)) - (test) - Has the XEP for TEST in the backtrace, not the TEST frame itself. - (sparc and x86 at least) - - Since SBCL 0.8.20.1 this is hidden unless *SHOW-ENTRY-POINT-DETAILS* - is true (instead there appear two TEST frames at least on ppc). The - underlying cause seems to be that SB-C::TAIL-ANNOTATE will not merge - the tail-call for the XEP, since Python has by that time proved that - the function can never return; same happens if the function holds an - unconditional call to ERROR. - 356: PCL corruption (reported by Bruno Haible) After the "layout depth conflict" error, the CLOS is left in a state where diff --git a/NEWS b/NEWS index 131a63c..8d233a1 100644 --- a/NEWS +++ b/NEWS @@ -42,6 +42,9 @@ method specializer used to confuse permuation vector optimization. * bug fix: system inserted bogus implicit type declarations for local special variables in DEFMETHOD bodies. + * bug fix: #354; duplicated frames in backtraces due to + non-tail-call-optimized XEPs to functions with return type NIL + have been elimited. changes in sbcl-1.0.23 relative to 1.0.22: * enhancement: when disassembling method functions, disassembly diff --git a/src/compiler/ir1opt.lisp b/src/compiler/ir1opt.lisp index 9fe8589..a5a8969 100644 --- a/src/compiler/ir1opt.lisp +++ b/src/compiler/ir1opt.lisp @@ -758,6 +758,14 @@ (values)) +(defun xep-tail-combination-p (node) + (and (combination-p node) + (let* ((lvar (combination-lvar node)) + (dest (when (lvar-p lvar) (lvar-dest lvar))) + (lambda (when (return-p dest) (return-lambda dest)))) + (and (lambda-p lambda) + (eq :external (lambda-kind lambda)))))) + ;;; If NODE doesn't return (i.e. return type is NIL), then terminate ;;; the block there, and link it to the component tail. ;;; @@ -783,7 +791,10 @@ (declare (ignore lvar)) (unless (or (and (eq node (block-last block)) (eq succ tail)) (block-delete-p block)) - (when (eq (node-derived-type node) *empty-type*) + ;; Even if the combination will never return, don't terminate if this + ;; is the tail call of a XEP: doing that would inhibit TCO. + (when (and (eq (node-derived-type node) *empty-type*) + (not (xep-tail-combination-p node))) (cond (ir1-converting-not-optimizing-p (cond ((block-last block) diff --git a/tests/debug.impure.lisp b/tests/debug.impure.lisp index e281214..e0ca3b9 100644 --- a/tests/debug.impure.lisp +++ b/tests/debug.impure.lisp @@ -257,6 +257,16 @@ `(let ((sb-debug:*show-entry-point-details* ,bool)) ,@body)) +(defun bug-354 (x) + (error "XEPs in backtraces: ~S" x)) + +(with-test (:name :bug-354) + (with-details t + (assert (not (verify-backtrace (lambda () (bug-354 354)) + '((bug-354 &rest) + ((sb-c::tl-xep bug-354) &rest)))))) + (assert (verify-backtrace (lambda () (bug-354 354)) '((bug-354 354))))) + ;;; FIXME: This test really should be broken into smaller pieces (with-test (:name (:backtrace :misc) :fails-on '(or (and :x86 (or :sunos)) (and :x86-64 :darwin))) diff --git a/tests/eval.impure.lisp b/tests/eval.impure.lisp index 2e6d502..c79066a 100644 --- a/tests/eval.impure.lisp +++ b/tests/eval.impure.lisp @@ -237,4 +237,16 @@ (declare (optimize speed)) (+ x y))))))) +(with-test (:name :bug-238) + (let ((sb-ext:*evaluator-mode* :compile)) + (handler-bind ((sb-ext:compiler-note #'error)) + (eval '(defclass bug-238 () ())) + (eval '(defmethod bug-238 ((x bug-238) (bug-238 bug-238)) + (call-next-method))) + (eval '(handler-case + (with-input-from-string (*query-io* " no") + (yes-or-no-p)) + (simple-type-error () 'error))) + t))) + ;;; success diff --git a/version.lisp-expr b/version.lisp-expr index dcaced8..3b61640 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.23.59" +"1.0.23.60" -- 1.7.10.4