1.0.17.28: fix bug in the newfangled constant dumping scheme
authorNikodemus Siivola <nikodemus@random-state.net>
Thu, 5 Jun 2008 16:32:37 +0000 (16:32 +0000)
committerNikodemus Siivola <nikodemus@random-state.net>
Thu, 5 Jun 2008 16:32:37 +0000 (16:32 +0000)
 * When MAYBE-EMIT-MAKE-LOAD-FORMS elects to use the name to dump
   something, it better use the name to refer to the _whole_ object,
   and not just a subpart...

 * Use XSET for niceness in there as well. ...but XSET should really
   be replaced by a sane tree-based version...

 * Test-case by Kevin Reid.

src/compiler/ir1tran.lisp
tests/compiler.impure.lisp
version.lisp-expr

index 869d1cd..676ed9a 100644 (file)
 ;;; processed with MAKE-LOAD-FORM. We have to be careful, because
 ;;; CONSTANT might be circular. We also check that the constant (and
 ;;; any subparts) are dumpable at all.
-(eval-when (:compile-toplevel :load-toplevel :execute)
-  ;; The EVAL-WHEN is necessary for #.(1+ LIST-TO-HASH-TABLE-THRESHOLD)
-  ;; below. -- AL 20010227
-  (def!constant list-to-hash-table-threshold 32))
 (defun maybe-emit-make-load-forms (constant &optional (name nil namep))
-  (let ((things-processed nil)
-        (count 0))
-    ;; FIXME: Does this LIST-or-HASH-TABLE messiness give much benefit?
-    (declare (type (or list hash-table) things-processed)
-             (type (integer 0 #.(1+ list-to-hash-table-threshold)) count)
-             (inline member))
-    (labels ((grovel (value)
+  (let ((xset (alloc-xset)))
+    (labels ((trivialp (value)
+               (typep value
+                      '(or #-sb-xc-host unboxed-array
+                        #+sb-xc-host (simple-array (unsigned-byte 8) (*))
+                        symbol
+                        number
+                        character
+                        string)))
+             (grovel (value)
                ;; Unless VALUE is an object which which obviously
                ;; can't contain other objects
-               (unless (typep value
-                              '(or #-sb-xc-host unboxed-array
-                                #+sb-xc-host (simple-array (unsigned-byte 8) (*))
-                                symbol
-                                number
-                                character
-                                string))
-                 (etypecase things-processed
-                   (list
-                    (when (member value things-processed :test #'eq)
-                      (return-from grovel nil))
-                    (push value things-processed)
-                    (incf count)
-                    (when (> count list-to-hash-table-threshold)
-                      (let ((things things-processed))
-                        (setf things-processed
-                              (make-hash-table :test 'eq))
-                        (dolist (thing things)
-                          (setf (gethash thing things-processed) t)))))
-                   (hash-table
-                    (when (gethash value things-processed)
-                      (return-from grovel nil))
-                    (setf (gethash value things-processed) t)))
+               (unless (trivialp value)
+                 (if (xset-member-p value xset)
+                     (return-from grovel nil)
+                     (add-to-xset value xset))
                  (typecase value
                    (cons
                     (grovel (car value))
                     (if namep
                         ;; We can dump arbitrary named constant references by
                         ;; using the name.
-                        (emit-make-load-form value name)
+                        (progn
+                          (emit-make-load-form constant name)
+                          (return-from maybe-emit-make-load-forms (values)))
                         ;; In the target SBCL, we can dump any instance, but
                         ;; in the cross-compilation host, %INSTANCE-FOO
                         ;; functions don't work on general instances, only on
index 89a9d83..2502ae2 100644 (file)
 (defconstant +born-to-coalesce4+ '(foo bar "zot" 123 (nested "quux") #*0101110010))
 (assert-coalescing '+born-to-coalesce4+)
 
+(defclass some-constant-thing () ())
+
+;;; correct handling of nested things loaded via SYMBOL-VALUE
+(defvar *sneaky-nested-thing* (list (make-instance 'some-constant-thing)))
+(defconstant +sneaky-nested-thing+ *sneaky-nested-thing*)
+(multiple-value-bind (file-fun core-fun) (compile2 '(lambda () +sneaky-nested-thing+))
+  (assert (eq *sneaky-nested-thing* (funcall file-fun)))
+  (assert (eq *sneaky-nested-thing* (funcall core-fun))))
+
 ;;; catch constant modifications thru undefined variables
 (defun sneak-set-dont-set-me (x)
   (ignore-errors (setq dont-set-me x)))
 (defconstant dont-set-me 42)
 (assert (not (sneak-set-dont-set-me 13)))
 (assert (= 42 dont-set-me))
-(defclass some-constant-thing () ())
 (defun sneak-set-dont-set-me2 (x)
   (ignore-errors (setq dont-set-me2 x)))
 (defconstant dont-set-me2 (make-instance 'some-constant-thing))
index 5affd46..f365cc5 100644 (file)
@@ -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.17.27"
+"1.0.17.28"