0.9.1.38:
[sbcl.git] / src / code / target-sxhash.lisp
index 55d23c5..cbc2267 100644 (file)
   (declare (optimize (speed 3) (safety 0)))
   (declare (type string string))
   (declare (type index count))
-  (let ((result 0))
-    (declare (type (unsigned-byte 32) result))
-    (unless (typep string '(vector nil))
-      (dotimes (i count)
-       (declare (type index i))
-       (setf result
-             (ldb (byte 32 0)
-                  (+ result (char-code (aref string i)))))
-       (setf result
-             (ldb (byte 32 0)
-                  (+ result (ash result 10))))
-       (setf result
-             (logxor result (ash result -6)))))
-    (setf result
-         (ldb (byte 32 0)
-              (+ result (ash result 3))))
-    (setf result
-         (logxor result (ash result -11)))
-    (setf result
-         (ldb (byte 32 0)
-              (logxor result (ash result 15))))
-    (logand result most-positive-fixnum)))
+  (macrolet ((set-result (form)
+              `(setf result (ldb (byte #.sb!vm:n-word-bits 0) ,form))))
+    (let ((result 0))
+      (declare (type (unsigned-byte #.sb!vm:n-word-bits) result))
+      (unless (typep string '(vector nil))
+       (dotimes (i count)
+         (declare (type index i))
+         (set-result (+ result (char-code (aref string i))))
+         (set-result (+ result (ash result 10)))
+         (set-result (logxor result (ash result -6)))))
+      (set-result (+ result (ash result 3)))
+      (set-result (logxor result (ash result -11)))
+      (set-result (logxor result (ash result 15)))
+      (logand result most-positive-fixnum))))
 ;;; test:
 ;;;   (let ((ht (make-hash-table :test 'equal)))
 ;;;     (do-all-symbols (symbol)
                          (mixf result (sxhash-number (realpart x)))
                          (mixf result (sxhash-number (imagpart x)))
                          result))))
-          (sxhash-recurse (x &optional (depthoid +max-hash-depthoid+))
+          (sxhash-recurse (x depthoid)
             (declare (type index depthoid))
             (typecase x
-              (cons
-               (if (plusp depthoid)
-                   (mix (sxhash-recurse (car x) (1- depthoid))
-                        (sxhash-recurse (cdr x) (1- depthoid)))
-                   261835505))
+              ;; we test for LIST here, rather than CONS, because the
+              ;; type test for CONS is in fact the test for
+              ;; LIST-POINTER-LOWTAG followed by a negated test for
+              ;; NIL.  If we're going to have to test for NIL anyway,
+              ;; we might as well do it explicitly and pick off the
+              ;; answer.  -- CSR, 2004-07-14
+              (list
+               (if (null x)
+                   (sxhash x) ; through DEFTRANSFORM
+                   (if (plusp depthoid)
+                       (mix (sxhash-recurse (car x) (1- depthoid))
+                            (sxhash-recurse (cdr x) (1- depthoid)))
+                       261835505)))
               (instance
                (if (or (typep x 'structure-object) (typep x 'condition))
                    (logxor 422371266
               (number (sxhash-number x))
               (generic-function (sxhash-instance x))
               (t 42))))
-    (sxhash-recurse x)))
+    (sxhash-recurse x +max-hash-depthoid+)))
 \f
 ;;;; the PSXHASH function
 
         (name (classoid-name classoid))
         (result (mix (sxhash name) (the fixnum 79867))))
     (declare (type fixnum result))
-    (dotimes (i (min depthoid (1- length)))
+    (dotimes (i (min depthoid (- length 1 (layout-n-untagged-slots layout))))
       (declare (type fixnum i))
       (let ((j (1+ i))) ; skipping slot #0, which is for LAYOUT
        (declare (type fixnum j))
        (mixf result
              (psxhash (%instance-ref key j)
                       (1- depthoid)))))
+    ;; KLUDGE: Should hash untagged slots, too.  (Although +max-hash-depthoid+
+    ;; is pretty low currently, so they might not make it into the hash
+    ;; value anyway.)
     result))
 
 (defun list-psxhash (key depthoid)