X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fsxhash.lisp;h=8b13e798d14521a1b3c52713948e62d6b60e16a0;hb=dca55270cf662763243dfc8ee207370473da2a6f;hp=2db5a484baed424264714a1aec519afa7cd36997;hpb=6973177fbe23d007655345c1fe2e0d6a5e397aa5;p=sbcl.git diff --git a/src/code/sxhash.lisp b/src/code/sxhash.lisp index 2db5a48..8b13e79 100644 --- a/src/code/sxhash.lisp +++ b/src/code/sxhash.lisp @@ -38,10 +38,56 @@ ;;; simple. (deftransform sxhash ((x) (fixnum)) '(logand most-positive-fixnum - (logxor x - (ash x -3) ; to get sign bit into hash + (logxor (ash (logand x (ash most-positive-fixnum -4)) 4) + (ash x -1) ; to get sign bit into hash 361475658))) +;;; SXHASH of SIMPLE-BIT-VECTOR values is defined as a DEFTRANSFORM +;;; because it is endian-dependent. +(deftransform sxhash ((x) (simple-bit-vector)) + `(let ((result 410823708)) + (declare (type fixnum result)) + (let ((length (length x))) + (cond + ((= length 0) (mix result (sxhash 0))) + (t + (mixf result (sxhash (length x))) + (do* ((i sb!vm:vector-data-offset (+ i 1)) + ;; FIXME: should we respect DEPTHOID? SXHASH on + ;; strings doesn't seem to... + (end-1 (+ sb!vm:vector-data-offset + (floor (1- length) sb!vm:n-word-bits)))) + ((= i end-1) + (let ((num + (logand + (ash (1- (ash 1 (mod length sb!vm:n-word-bits))) + ,(ecase sb!c:*backend-byte-order* + (:little-endian 0) + (:big-endian + '(- 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)) + (:big-endian + '(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)) + ;; FIXME: I'm not certain that + ;; N-LOWTAG-BITS is the clearest way of + ;; expressing this: it's essentially the + ;; difference between `(UNSIGNED-BYTE + ;; ,SB!VM:N-WORD-BITS) and (AND FIXNUM + ;; UNSIGNED-BYTE). + (:big-endian + '(ash num (- sb!vm:n-lowtag-bits)))))))))))) + ;;; Some other common SXHASH cases are defined as DEFTRANSFORMs in ;;; order to avoid having to do TYPECASE at runtime. ;;; @@ -52,10 +98,12 @@ ;;; easily do this optimization in the cross-compiler, and SBCL itself ;;; doesn't seem to need this optimization, so we don't try. (deftransform sxhash ((x) (simple-string)) - (if #+sb-xc-host nil #-sb-xc-host (constant-continuation-p x) - (sxhash (continuation-value x)) + (if #+sb-xc-host nil #-sb-xc-host (constant-lvar-p x) + (sxhash (lvar-value x)) '(%sxhash-simple-string x))) (deftransform sxhash ((x) (symbol)) - (if #+sb-xc-host nil #-sb-xc-host (constant-continuation-p x) - (sxhash (continuation-value x)) + (if #+sb-xc-host nil #-sb-xc-host (constant-lvar-p x) + (sxhash (lvar-value x)) '(%sxhash-simple-string (symbol-name x)))) + +