COMPOUND-OBJECT-P, and (LABELS MAYBE-EMIT-MAKE-LOAD-FORMS GROVEL)
through TYPEP UNBOXED-ARRAY, within the compiler itself.
--------------------------------------------------------------------------------
+#18
+(lambda (x) (declare (null x)) (sxhash x)) goes through SYMBOL-HASH
+rather than either constant-folding or manipulating NIL-VALUE or
+NULL-TN directly.
+--------------------------------------------------------------------------------
(deftransform sxhash ((x) (symbol))
(if #+sb-xc-host nil #-sb-xc-host (constant-lvar-p x)
(sxhash (lvar-value x))
- ;; Cache the value of the symbol's sxhash in the symbol-hash slot.
- '(let ((result (symbol-hash x)))
- ;; 0 marks uninitialized slot. We can't use negative values
- ;; for the uninitialized slots since NIL might be located so
- ;; high in memory on some platforms that its SYMBOL-HASH
- ;; (which contains NIL itself) is a negative fixnum.
- (if (= 0 result)
- (let ((sxhash (%sxhash-simple-string (symbol-name x))))
- ;; We could do a (logior sxhash #x10000000) to ensure
- ;; that we never store a 0 in the slot. However, it's
- ;; such an unlikely event (1/5e8?) that it makes more
- ;; sense to optimize for the common case...
- (%set-symbol-hash x sxhash)
- sxhash)
- result))))
+ (if (csubtypep (lvar-type x) (specifier-type 'null))
+ ;; FIXME: this isn't in fact as optimized as it could be;
+ ;; this does a memory load, whereas (because we know the
+ ;; layout of NIL) we could simply take the address of NIL
+ ;; (or the contents of NULL-TN) and mask off the appropriate
+ ;; bits, since SYMBOL-HASH of NIL is also NIL's CDR, which
+ ;; is NIL. -- CSR, 2004-07-14
+ '(symbol-hash x)
+ ;; Cache the value of the symbol's sxhash in the symbol-hash
+ ;; slot.
+ '(let ((result (symbol-hash x)))
+ ;; 0 marks uninitialized slot. We can't use negative
+ ;; values for the uninitialized slots since NIL might be
+ ;; located so high in memory on some platforms that its
+ ;; SYMBOL-HASH (which contains NIL itself) is a negative
+ ;; fixnum.
+ (if (= 0 result)
+ (let ((sxhash (%sxhash-simple-string (symbol-name x))))
+ ;; We could do a (logior sxhash #x10000000) to
+ ;; ensure that we never store a 0 in the
+ ;; slot. However, it's such an unlikely event
+ ;; (1/5e8?) that it makes more sense to optimize for
+ ;; the common case...
+ (%set-symbol-hash x sxhash)
+ sxhash)
+ result)))))
(sxhash-recurse (x &optional (depthoid +max-hash-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
(defknown hash-table-size (hash-table) index (flushable))
(defknown hash-table-test (hash-table) symbol (foldable flushable))
(defknown sxhash (t) (integer 0 #.sb!xc:most-positive-fixnum)
- (foldable flushable))
+ (#-sb-xc-host foldable flushable))
\f
;;;; from the "Arrays" chapter
;;; NIL is both SYMBOL and LIST
(dolist (fun '(sxhash sb-impl::psxhash))
- (assert (= (funcall fun nil)
+ (assert (= (eval `(,fun nil))
+ (funcall fun nil)
(funcall (compile nil `(lambda (x)
(declare (symbol x))
(,fun x)))
(funcall (compile nil `(lambda (x)
(declare (list x))
(,fun x)))
+ nil)
+ (funcall (compile nil `(lambda (x)
+ (declare (null x))
+ (,fun x)))
nil))))
;;; success
;;; 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".)
-"0.8.12.34"
+"0.8.12.35"