;;; order to avoid boxing.
(deftransform sxhash ((x) (single-float))
'(let* ((val (+ 0.0f0 x))
- (bits (single-float-bits val)))
+ (bits (logand (single-float-bits val) #.(1- (ash 1 32)))))
(logxor 66194023
(sxhash (the fixnum
(logand most-positive-fixnum
(ash bits -7))))))))
(deftransform sxhash ((x) (double-float))
'(let* ((val (+ 0.0d0 x))
- (hi (double-float-high-bits val))
+ (hi (logand (double-float-high-bits val) #.(1- (ash 1 32))))
(lo (double-float-low-bits val))
(hilo (logxor hi lo)))
(logxor 475038542
;;; simple.
(deftransform sxhash ((x) (fixnum))
'(logand most-positive-fixnum
- (logxor (ash (logand x (ash most-positive-fixnum -4)) 4)
- (ash x -1) ; to get sign bit into hash
+ (logxor (ash (logand x (ash most-positive-fixnum -4)) 4)
+ (logand (ash x -1) most-positive-fixnum) ; to get sign bit into hash
361475658)))
;;; SXHASH of SIMPLE-BIT-VECTOR values is defined as a DEFTRANSFORM
'(- sb!vm:n-word-bits
(mod length sb!vm:n-word-bits)))))
(%raw-bits x i))))
- (declare (type (unsigned-byte 32) num))
(mix result ,(ecase sb!c:*backend-byte-order*
(:little-endian
'(logand num most-positive-fixnum))
'(ash num (- sb!vm:n-lowtag-bits)))))))
(declare (type index i end-1))
(let ((num (%raw-bits x i)))
- (declare (type (unsigned-byte 32) num))
(mixf result ,(ecase sb!c:*backend-byte-order*
(:little-endian
'(logand num most-positive-fixnum))
(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 (logor 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)))))