X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fcode%2Farray.lisp;h=286d197b9a097999a0e57b00c98d24e7ed4dbe3e;hb=f3a7c6b54880895d1598b1844d7e6eba98af9e53;hp=00444b0ef016a6b1663fccbeb8ce878cf1e6373d;hpb=9769174fc3e1a9d840712a694f61c6051e161cd7;p=sbcl.git diff --git a/src/code/array.lisp b/src/code/array.lisp index 00444b0..286d197 100644 --- a/src/code/array.lisp +++ b/src/code/array.lisp @@ -56,6 +56,19 @@ (values vector index)) (values array index))) +(declaim (inline simple-vector-compare-and-swap)) +(defun simple-vector-compare-and-swap (vector index old new) + #!+(or x86 x86-64) + (%simple-vector-compare-and-swap vector + (%check-bound vector (length vector) index) + old + new) + #!-(or x86 x86-64) + (let ((n-old (svref vector index))) + (when (eq old n-old) + (setf (svref vector index) new)) + n-old)) + ;;; It'd waste space to expand copies of error handling in every ;;; inline %WITH-ARRAY-DATA, so we have them call this function ;;; instead. This is just a wrapper which is known never to return. @@ -328,52 +341,59 @@ of specialized arrays is supported." ;;; the type information is available. Finally, for each of these ;;; routines also provide a slow path, taken for arrays that are not ;;; vectors or not simple. -(macrolet ((define (accessor-name slow-accessor-name table-name extra-params +(macrolet ((%define (table-name extra-params) + `(funcall + (the function + (let ((tag 0) + (offset + #.(ecase sb!c:*backend-byte-order* + (:little-endian + (- sb!vm:other-pointer-lowtag)) + (:big-endian + (- (1- sb!vm:n-word-bytes) sb!vm:other-pointer-lowtag))))) + ;; WIDETAG-OF needs extra code to handle + ;; LIST and FUNCTION lowtags. We're only + ;; dispatching on other pointers, so let's + ;; do the lowtag extraction manually. + (when (sb!vm::%other-pointer-p array) + (setf tag + (sb!sys:sap-ref-8 (int-sap (get-lisp-obj-address array)) + offset))) + ;; SYMBOL-GLOBAL-VALUE is a performance hack + ;; for threaded builds. + (svref (sb!vm::symbol-global-value ',table-name) tag))) + array index ,@extra-params)) + (define (accessor-name slow-accessor-name table-name extra-params check-bounds) - `(progn - (defvar ,table-name) - (defun ,accessor-name (array index ,@extra-params) - (declare (optimize speed - ;; (SAFETY 0) is ok. All calls to - ;; these functions are generated by - ;; the compiler, so argument count - ;; checking isn't needed. Type checking - ;; is done implicitly via the widetag - ;; dispatch. - (safety 0))) - #1=(funcall (the function - (let ((tag 0)) - ;; WIDETAG-OF needs extra code to - ;; handle LIST and FUNCTION - ;; lowtags. We're only dispatching - ;; on other pointers, so let's do - ;; the lowtag extraction manually. - (when (sb!vm::%other-pointer-p array) - (setf tag (sb!sys:sap-ref-8 - (int-sap (get-lisp-obj-address array)) - (- sb!vm:other-pointer-lowtag)))) - ;; SYMBOL-GLOBAL-VALUE is a performance hack - ;; for threaded builds. - (svref (sb!vm::symbol-global-value ',table-name) - tag))) - array index ,@extra-params)) - (defun ,slow-accessor-name (array index ,@extra-params) - (declare (optimize speed (safety 0))) - (if (not (%array-displaced-p array)) - ;; The reasonably quick path of non-displaced complex - ;; arrays. - (let ((array (%array-data-vector array))) - #1#) - ;; The real slow path. - (with-array-data - ((vector array) - (index (locally - (declare (optimize (speed 1) (safety 1))) - (,@check-bounds index))) - (end) - :force-inline t) - (declare (ignore end)) - (,accessor-name vector index ,@extra-params))))))) + `(progn + (defvar ,table-name) + (defun ,accessor-name (array index ,@extra-params) + (declare (optimize speed + ;; (SAFETY 0) is ok. All calls to + ;; these functions are generated by + ;; the compiler, so argument count + ;; checking isn't needed. Type checking + ;; is done implicitly via the widetag + ;; dispatch. + (safety 0))) + (%define ,table-name ,extra-params)) + (defun ,slow-accessor-name (array index ,@extra-params) + (declare (optimize speed (safety 0))) + (if (not (%array-displaced-p array)) + ;; The reasonably quick path of non-displaced complex + ;; arrays. + (let ((array (%array-data-vector array))) + (%define ,table-name ,extra-params)) + ;; The real slow path. + (with-array-data + ((vector array) + (index (locally + (declare (optimize (speed 1) (safety 1))) + (,@check-bounds index))) + (end) + :force-inline t) + (declare (ignore end)) + (,accessor-name vector index ,@extra-params))))))) (define hairy-data-vector-ref slow-hairy-data-vector-ref *data-vector-reffers* nil (progn)) (define hairy-data-vector-set slow-hairy-data-vector-set @@ -433,7 +453,7 @@ of specialized arrays is supported." ,@(loop for widetag in '(sb!vm:complex-vector-widetag sb!vm:complex-vector-nil-widetag sb!vm:complex-bit-vector-widetag - sb!vm:complex-character-string-widetag + #!+sb-unicode sb!vm:complex-character-string-widetag sb!vm:complex-base-string-widetag sb!vm:simple-array-widetag sb!vm:complex-array-widetag) @@ -462,6 +482,9 @@ of specialized arrays is supported." (defun data-vector-ref (array index) (hairy-data-vector-ref array index)) +(defun data-vector-ref-with-offset (array index offset) + (hairy-data-vector-ref array (+ index offset))) + ;;; SUBSCRIPTS has a dynamic-extent list structure and is destroyed (defun %array-row-major-index (array subscripts &optional (invalid-index-error-p t))