0.pre7.111:
authorWilliam Harold Newman <william.newman@airmail.net>
Wed, 2 Jan 2002 18:52:59 +0000 (18:52 +0000)
committerWilliam Harold Newman <william.newman@airmail.net>
Wed, 2 Jan 2002 18:52:59 +0000 (18:52 +0000)
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

14 files changed:
BUGS
TODO
build-order.lisp-expr
src/code/condition.lisp
src/compiler/alpha/call.lisp
src/compiler/dump.lisp
src/compiler/entry.lisp
src/compiler/generic/target-core.lisp
src/compiler/ir1tran.lisp
src/compiler/ir2tran.lisp
src/compiler/locall.lisp
src/compiler/tn.lisp
src/compiler/x86/call.lisp
version.lisp-expr

diff --git a/BUGS b/BUGS
index 62ffc35..e50ba73 100644 (file)
--- 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 (file)
--- 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)
index 3f116c8..a53bf78 100644 (file)
  ;; 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
index d52aecc..bf840db 100644 (file)
                                (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)
 
               (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))
        (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.)
             (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))
index ddd9281..8b38643 100644 (file)
@@ -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))
index bb1aacf..3ec6377 100644 (file)
   ;; 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 (<code-handle> . <offset>), where <code-handle>
   ;; is the offset in the table of the code object needing to be
   ;; patched, and <offset> is the offset that must be patched.
       ;; 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
                       (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
       (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))
index 33ea6cc..8b7bfd6 100644 (file)
@@ -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))
 
index 0ef862b..dcc4a97 100644 (file)
@@ -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)
index 8f68038..0f40ec0 100644 (file)
   (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)
index 8fa72f4..0634aeb 100644 (file)
 
 ;;; 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
   (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)
index 0622e7e..855a877 100644 (file)
 ;;;
 ;;; 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
                      ;; 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)))))
index 4132092..e0eb8f4 100644 (file)
 
 ;;; 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*))
index 58522f4..6b4bf08 100644 (file)
   (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))))
index c04d70c..6ca75f7 100644 (file)
@@ -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"