From f9d6d21a7f54638292214ceb9886edc03b99d545 Mon Sep 17 00:00:00 2001 From: William Harold Newman Date: Wed, 2 Jan 2002 18:52:59 +0000 Subject: [PATCH] 0.pre7.111: hunting bug 138... ...Poking around in the bug 138 test case, I found that the failure is occurring for a LAMBDA which represents the inline expansion of LAYOUT-INHERITS. It seems correct for :INLINE LAMBDAs not to be in COMPONENT-LAMBDAS, so it looks as though the bug is in the AVER, not the code it's trying to protect, so I added a new :INLINE case to the check logic. Alas, that only converted bug 138a into bug 138b. ...added some assertions and comments hunting for 138b redid DUMP-CODE-OBJECT loop for clarity as LOOP not DO --- BUGS | 37 ++++++++++++++++++++++++++++++--- TODO | 8 ++++++- build-order.lisp-expr | 4 ++-- src/code/condition.lisp | 16 +++++++------- src/compiler/alpha/call.lisp | 6 +++--- src/compiler/dump.lisp | 20 +++++++++++++----- src/compiler/entry.lisp | 1 - src/compiler/generic/target-core.lisp | 4 ++-- src/compiler/ir1tran.lisp | 2 +- src/compiler/ir2tran.lisp | 30 +++++++++++++++++++++++--- src/compiler/locall.lisp | 15 ++++++++++++- src/compiler/tn.lisp | 2 +- src/compiler/x86/call.lisp | 17 ++++++++++----- version.lisp-expr | 2 +- 14 files changed, 127 insertions(+), 37 deletions(-) diff --git a/BUGS b/BUGS index 62ffc35..e50ba73 100644 --- a/BUGS +++ b/BUGS @@ -1283,9 +1283,10 @@ Error in function C::GET-LAMBDA-TO-COMPILE: "SB-INT:&MORE processor". 138: - a cross-compiler bug in sbcl-0.pre7.107 + a pair of cross-compiler bugs in sbcl-0.pre7.107 - $ cat > /tmp/bug139.lisp << EOF +138a: + $ cat > /tmp/bug138.lisp << EOF (in-package "SB!KERNEL") (defun f-c-l (name parent-types) (let* ((cpl (mapcar (lambda (x) @@ -1300,7 +1301,7 @@ Error in function C::GET-LAMBDA-TO-COMPILE: EOF $ sbcl --core output/after-xc.core ... - * (target-compile-file "/tmp/bug139.lisp") + * (target-compile-file "/tmp/bug138.lisp") ... internal error, failed AVER: "(COMMON-LISP:MEMBER SB!C::FUN (SB!C::COMPONENT-LAMBDAS SB!C:COMPONENT))" @@ -1312,6 +1313,36 @@ Error in function C::GET-LAMBDA-TO-COMPILE: related weirdness: Using #'(LAMBDA (X) ...) instead of (LAMBDA (X) ...) makes the assertion failure go away. +138b: + Even when you relax the AVER that fails in 138a, there's another + problem cross-compiling the same code: + internal error, failed AVER: + "(COMMON-LISP:ZEROP + (COMMON-LISP:HASH-TABLE-COUNT + (SB!FASL::FASL-OUTPUT-PATCH-TABLE SB!FASL:FASL-OUTPUT)))" + + The same problem appears in the simpler test case + (in-package "SB!KERNEL") + (defun f-c-l () + (let ((cpl (foo (lambda (x) + (condition-class-cpl x)))) + (new-inherits (layout-inherits cond-layout))) + (layout-inherits olayout))) + + Changing CONDITION-CLASS-CPL or (either of the calls to) LAYOUT-INHERITS + to arbitrary nonmagic not-defined-yet just-do-a-full-call functions makes + the problem go away. Also, even in this simpler test case which fails + on a very different AVER, the 138a weirdness about s/(lambda/#'(lambda/ + making the problem go away is preserved. + + I still haven't found any way to make this happen in the ordinary + (not cross-) SBCL compiler, nor in CMU CL. + +138c: + In sbcl-0.pre7.111 I added an assertion upstream, in IR2-CONVERT-CLOSURE, + which fails for the test case above but doesn't keep the system + from cross-compiling itself or passing its tests. + 139: In sbcl-0.pre7.107, (DIRECTORY "*.*") is broken, as reported by Nathan Froyd sbcl-devel 2001-12-28. diff --git a/TODO b/TODO index 887dc4f..6c8c147 100644 --- a/TODO +++ b/TODO @@ -11,6 +11,7 @@ for 0.7.0: ** finished s/FUNCTION/FUN/ ** s/VARIABLE/VAR/ ** perhaps s/DEF-FROB/DEF/ or s/DEF-FROB/DEFINE/ +* Perhaps rename "cold" stuff (e.g. SB-COLD and src/cold/) to "boot". * global style systematization: ** s/#'(lambda/(lambda/ * pending patches and bug reports that go in (or else get handled @@ -22,7 +23,12 @@ for early 0.7.x: * patches postponed until after 0.7.0: ** Christophe Rhodes "rough patch to fix bug 106" 2001-10-28 ** Alexey Dejneka "bug 111" 2001-12-30 -* building with CLISP (or explaining why not) +* building with CLISP (or explaining why not). This will likely involve + a rearrangement of the build system so that it never renames + the output from COMPILE-FILE, because CLISP's COMPILE-FILE + outputs two (!) files and as far as I can tell LOAD uses both + of them. Since I have other motivations for this rearrangement + besides CLISPiosyncrasies, I'm reasonably motivated to do it. * urgent EVAL/EVAL-WHEN/%COMPILE/DEFUN/DEFSTRUCT cleanup: ** fixed bug 137 * faster bootstrapping (both make.sh and slam.sh) diff --git a/build-order.lisp-expr b/build-order.lisp-expr index 3f116c8..a53bf78 100644 --- a/build-order.lisp-expr +++ b/build-order.lisp-expr @@ -299,8 +299,8 @@ ;; for e.g. SPECIFIER-TYPE, needed by primtype.lisp ("src/code/early-type") - ;; FIXME: Classic CMU CL had SAFETY 2 DEBUG 2 set around the compilation - ;; of "code/class". Why? + ;; FIXME: Classic CMU CL had (OPTIMIZE (SAFETY 2) (DEBUG 2) declared + ;; around the compilation of "code/class". Why? ("src/code/class") ;; The definition of CONDITION-CLASS depends on SLOT-CLASS, defined diff --git a/src/code/condition.lisp b/src/code/condition.lisp index d52aecc..bf840db 100644 --- a/src/code/condition.lisp +++ b/src/code/condition.lisp @@ -110,7 +110,7 @@ (declare (notinline sb!xc:find-class)) (find-class 'condition))) #'(lambda (cond stream) - (format stream "Condition ~S was signalled." (type-of cond)))) + (format stream "Condition ~S was signalled." (type-of cond)))) (eval-when (:compile-toplevel :load-toplevel :execute) @@ -119,8 +119,8 @@ (reverse (reduce #'append (mapcar #'(lambda (x) - (condition-class-cpl - (sb!xc:find-class x))) + (condition-class-cpl + (sb!xc:find-class x))) parent-types))))) (cond-layout (info :type :compiler-layout 'condition)) (olayout (info :type :compiler-layout name)) @@ -362,11 +362,11 @@ (dolist (reader (condition-slot-readers slot)) (setf (fdefinition reader) #'(lambda (condition) - (condition-reader-function condition name)))) + (condition-reader-function condition name)))) (dolist (writer (condition-slot-writers slot)) (setf (fdefinition writer) #'(lambda (new-value condition) - (condition-writer-function condition new-value name)))))) + (condition-writer-function condition new-value name)))))) ;; Compute effective slots and set up the class and hairy slots ;; (subsets of the effective slots.) @@ -482,10 +482,10 @@ (setq report (if (stringp arg) `#'(lambda (condition stream) - (declare (ignore condition)) - (write-string ,arg stream)) + (declare (ignore condition)) + (write-string ,arg stream)) `#'(lambda (condition stream) - (funcall #',arg condition stream)))))) + (funcall #',arg condition stream)))))) (:default-initargs (do ((initargs (rest option) (cddr initargs))) ((endp initargs)) diff --git a/src/compiler/alpha/call.lisp b/src/compiler/alpha/call.lisp index ddd9281..8b38643 100644 --- a/src/compiler/alpha/call.lisp +++ b/src/compiler/alpha/call.lisp @@ -85,9 +85,9 @@ (make-normal-tn *fixnum-primitive-type*))) -;;; This function is called by the Entry-Analyze phase, allowing -;;; VM-dependent initialization of the IR2-Component structure. We -;;; push placeholder entries in the Constants to leave room for +;;; This function is called by the ENTRY-ANALYZE phase, allowing +;;; VM-dependent initialization of the IR2-COMPONENT structure. We +;;; push placeholder entries in the CONSTANTS to leave room for ;;; additional noise in the code object header. (!def-vm-support-routine select-component-format (component) (declare (type component component)) diff --git a/src/compiler/dump.lisp b/src/compiler/dump.lisp index bb1aacf..3ec6377 100644 --- a/src/compiler/dump.lisp +++ b/src/compiler/dump.lisp @@ -43,11 +43,11 @@ ;; an alist (PACKAGE . OFFSET) of the table offsets for each package ;; we have currently located. (packages () :type list) - ;; a table mapping from the Entry-Info structures for dumped XEPs to + ;; a table mapping from the ENTRY-INFO structures for dumped XEPs to ;; the table offsets of the corresponding code pointers (entry-table (make-hash-table :test 'eq) :type hash-table) ;; a table holding back-patching info for forward references to XEPs. - ;; The key is the Entry-Info structure for the XEP, and the value is + ;; The key is the ENTRY-INFO structure for the XEP, and the value is ;; a list of conses ( . ), where ;; is the offset in the table of the code object needing to be ;; patched, and is the offset that must be patched. @@ -994,9 +994,9 @@ ;; far as I know no modern CMU CL does either -- WHN ;; 2001-10-05). So might we be able to get rid of trace tables? - ;; Dump the constants, noting any :entries that have to be fixed up. - (do ((i sb!vm:code-constants-offset (1+ i))) - ((>= i header-length)) + ;; Dump the constants, noting any :ENTRY constants that have to + ;; be patched. + (loop for i from sb!vm:code-constants-offset below header-length do (let ((entry (aref constants i))) (etypecase entry (constant @@ -1008,10 +1008,19 @@ (handle (gethash info (fasl-output-entry-table fasl-output)))) + (declare (type sb!c::entry-info info)) (cond (handle (dump-push handle fasl-output)) (t + + ;; REMOVEME after fixing bug 138b. + #| + (unless (member info (sb!c::ir2-component-entries 2comp)) + (format t "~&i=~S~%" i) + (error "bogus FASL-OUTPUT-PATCH-TABLE value ~S" info)) + |# + (patches (cons info i)) (dump-fop 'fop-misc-trap fasl-output))))) (:load-time-value @@ -1051,6 +1060,7 @@ (dump-fixups fixups fasl-output) (dump-fop 'fop-sanctify-for-execution fasl-output) + (let ((handle (dump-pop fasl-output))) (dolist (patch (patches)) (push (cons handle (cdr patch)) diff --git a/src/compiler/entry.lisp b/src/compiler/entry.lisp index 33ea6cc..8b7bfd6 100644 --- a/src/compiler/entry.lisp +++ b/src/compiler/entry.lisp @@ -28,7 +28,6 @@ (setf (leaf-info fun) (make-entry-info))))) (compute-entry-info fun info) (push info (ir2-component-entries 2comp)))))) - (select-component-format component) (values)) diff --git a/src/compiler/generic/target-core.lisp b/src/compiler/generic/target-core.lisp index 0ef862b..dcc4a97 100644 --- a/src/compiler/generic/target-core.lisp +++ b/src/compiler/generic/target-core.lisp @@ -33,8 +33,8 @@ (note-function entry res object)))) -;;; Dump a component to core. We pass in the assembler fixups, code vector -;;; and node info. +;;; Dump a component to core. We pass in the assembler fixups, code +;;; vector and node info. (defun make-core-component (component segment length trace-table fixups object) (declare (type component component) (type sb!assem:segment segment) diff --git a/src/compiler/ir1tran.lisp b/src/compiler/ir1tran.lisp index 8f68038..0f40ec0 100644 --- a/src/compiler/ir1tran.lisp +++ b/src/compiler/ir1tran.lisp @@ -777,7 +777,7 @@ (values)) ;;; Convert a call to a local function. If the function has already -;;; been let converted, then throw FUN to LOCAL-CALL-LOSSAGE. This +;;; been LET converted, then throw FUN to LOCAL-CALL-LOSSAGE. This ;;; should only happen when we are converting inline expansions for ;;; local functions during optimization. (defun ir1-convert-local-combination (start cont form fun) diff --git a/src/compiler/ir2tran.lisp b/src/compiler/ir2tran.lisp index 8fa72f4..0634aeb 100644 --- a/src/compiler/ir2tran.lisp +++ b/src/compiler/ir2tran.lisp @@ -148,11 +148,11 @@ ;;; Emit code to load a function object representing LEAF into RES. ;;; This gets interesting when the referenced function is a closure: -;;; we must make the closure and move the closed over values into it. +;;; we must make the closure and move the closed-over values into it. ;;; ;;; LEAF is either a :TOPLEVEL-XEP functional or the XEP lambda for ;;; the called function, since local call analysis converts all -;;; closure references. If a TL-XEP, we know it is not a closure. +;;; closure references. If a :TOPLEVEL-XEP, we know it is not a closure. ;;; ;;; If a closed-over LAMBDA-VAR has no refs (is deleted), then we ;;; don't initialize that slot. This can happen with closures over @@ -163,14 +163,38 @@ (declare (type ref node) (type ir2-block block) (type functional leaf) (type tn res)) (unless (leaf-info leaf) - (setf (leaf-info leaf) (make-entry-info))) + (setf (leaf-info leaf) + (make-entry-info :name (functional-debug-name leaf)))) (let ((entry (make-load-time-constant-tn :entry leaf)) (closure (etypecase leaf (clambda + + ;; Check for some weirdness which came up in bug + ;; 138, 2002-01-02. + ;; + ;; The MAKE-LOAD-TIME-CONSTANT-TN call above puts + ;; an :ENTRY record into the + ;; IR2-COMPONENT-CONSTANTS table. The + ;; dump-a-COMPONENT code + ;; * treats every HANDLEless :ENTRY record into a + ;; patch, and + ;; * expects every patch to correspond to an + ;; IR2-COMPONENT-ENTRIES record. + ;; The IR2-COMPONENT-ENTRIES records are set by + ;; ENTRY-ANALYZE walking over COMPONENT-LAMBDAS. + ;; Bug 138b arose because there was a HANDLEless + ;; :ENTRY record which didn't correspond to an + ;; IR2-COMPONENT-ENTRIES record. That problem is + ;; hard to debug when it's caught at dump time, so + ;; this assertion tries to catch it here. + (aver (member leaf + (component-lambdas (lambda-component leaf)))) + (physenv-closure (get-lambda-physenv leaf))) (functional (aver (eq (functional-kind leaf) :toplevel-xep)) nil)))) + (cond (closure (let ((this-env (node-physenv node))) (vop make-closure node block entry (length closure) res) diff --git a/src/compiler/locall.lisp b/src/compiler/locall.lisp index 0622e7e..855a877 100644 --- a/src/compiler/locall.lisp +++ b/src/compiler/locall.lisp @@ -255,7 +255,7 @@ ;;; ;;; Note that there is a lot of action going on behind the scenes ;;; here, triggered by reference deletion. In particular, the -;;; COMPONENT-LAMBDAS are being hacked to remove newly deleted and let +;;; COMPONENT-LAMBDAS are being hacked to remove newly deleted and LET ;;; converted LAMBDAs, so it is important that the LAMBDA is added to ;;; the COMPONENT-LAMBDAS when it is. Also, the COMPONENT-NEW-FUNS may ;;; contain all sorts of drivel, since it is not updated when we @@ -283,6 +283,19 @@ ;; FUN becomes part of COMPONENT-LAMBDAS now. (aver (not (member fun (component-lambdas component)))) (push fun (component-lambdas component))) + ((eql (lambda-inlinep fun) :inline) + ;; FUNs marked :INLINE are sometimes in + ;; COMPONENT-LAMBDAS and sometimes not. I (WHN + ;; 2002-01-01) haven't figured this one out yet, + ;; so don't assert anything. + ;; + ;; (One possibility: LAMBDAs to represent the + ;; inline expansions of things which are defined + ;; elsewhere might not be in COMPONENT-LAMBDAS, + ;; which LAMBDAs to represent the inline + ;; expansions of local functions might in + ;; COMPONENT-LAMBDAS?) + (values)) (t ; FUN's old. ;; FUN should be in COMPONENT-LAMBDAS already. (aver (member fun (component-lambdas component))))) diff --git a/src/compiler/tn.lisp b/src/compiler/tn.lisp index 4132092..e0eb8f4 100644 --- a/src/compiler/tn.lisp +++ b/src/compiler/tn.lisp @@ -220,7 +220,7 @@ ;;; Return a load-time constant TN with the specified KIND and INFO. ;;; If the desired CONSTANTS entry already exists, then reuse it, -;;; otherwise allocate a anew load-time constant slot. +;;; otherwise allocate a new load-time constant slot. (defun make-load-time-constant-tn (kind info) (declare (type keyword kind)) (let* ((component (component-info *component-being-compiled*)) diff --git a/src/compiler/x86/call.lisp b/src/compiler/x86/call.lisp index 58522f4..6b4bf08 100644 --- a/src/compiler/x86/call.lisp +++ b/src/compiler/x86/call.lisp @@ -84,15 +84,22 @@ (list (make-stack-pointer-tn) (make-normal-tn *fixnum-primitive-type*))) -;;; This function is called by the Entry-Analyze phase, allowing +;;; This function is called by the ENTRY-ANALYZE phase, allowing ;;; VM-dependent initialization of the IR2-COMPONENT structure. We -;;; push placeholder entries in the Constants to leave room for +;;; push placeholder entries in the CONSTANTS to leave room for ;;; additional noise in the code object header. -;;; -;;; For the x86 the first constant is a pointer to a list of fixups, -;;; or NIL if the code object has none. (!def-vm-support-routine select-component-format (component) (declare (type component component)) + ;; The 1+ here is because for the x86 the first constant is a + ;; pointer to a list of fixups, or NIL if the code object has none. + ;; (If I understand correctly, the fixups are needed at GC copy + ;; time because the X86 code isn't relocatable.) + ;; + ;; KLUDGE: It'd be cleaner to have the fixups entry be a named + ;; element of the CODE (aka component) primitive object. However, + ;; it's currently a large, tricky, error-prone chore to change + ;; the layout of any primitive object, so for the foreseeable future + ;; we'll just live with this ugliness. -- WHN 2002-01-02 (dotimes (i (1+ code-constants-offset)) (vector-push-extend nil (ir2-component-constants (component-info component)))) diff --git a/version.lisp-expr b/version.lisp-expr index c04d70c..6ca75f7 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -18,4 +18,4 @@ ;;; for internal versions, especially for internal versions off the ;;; main CVS branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"0.pre7.110" +"0.pre7.111" -- 1.7.10.4