1.0.6.3: thread and interrupt safe CLOS cache
[sbcl.git] / src / pcl / dlisp.lisp
index 7ed3463..486541b 100644 (file)
@@ -23,6 +23,7 @@
 
 (in-package "SB-PCL")
 
+
 ;;;; some support stuff for getting a hold of symbols that we need when
 ;;;; building the discriminator codes. It's OK for these to be interned
 ;;;; symbols because we don't capture any user code in the scope in which
                                (fsc-instance-wrapper ,instance)))))
         (block access
           (when (and wrapper
-                     (/= (layout-clos-hash wrapper) 0)
+                     (not (zerop (layout-clos-hash wrapper)))
                      ,@(if (eql 1 1-or-2-class)
                            `((eq wrapper wrapper-0))
                            `((or (eq wrapper wrapper-0)
       (error "Every metatype is T."))
     `(prog ()
         (return
-          (let ((cache-vector (cache-vector ,cache-var))
-                (mask (cache-mask ,cache-var))
-                (size (cache-size ,cache-var))
-                (overflow (cache-overflow ,cache-var))
-                ,@wrapper-bindings)
-            (declare (fixnum size mask))
-            ,(emit-cache-lookup wrapper-vars miss-tag value-var)
+          (let ,wrapper-bindings
+            ,(emit-cache-lookup cache-var wrapper-vars miss-tag value-var)
             ,hit-form))
       ,miss-tag
         (return ,miss-form))))
 
-(defun emit-cache-lookup (wrapper-vars miss-tag value-reg)
-  (cond ((cdr wrapper-vars)
-         (emit-greater-than-1-dlap wrapper-vars miss-tag value-reg))
-        (value-reg
-         (emit-1-t-dlap (car wrapper-vars) miss-tag value-reg))
-        (t
-         (emit-1-nil-dlap (car wrapper-vars) miss-tag))))
-
-(defun emit-1-nil-dlap (wrapper miss-label)
-  `(let* ((primary ,(emit-1-wrapper-compute-primary-cache-location wrapper
-                                                                   miss-label))
-          (location primary))
-     (declare (fixnum primary location))
-     (block search
-       (loop (when (eq ,wrapper (cache-vector-ref cache-vector location))
-               (return-from search nil))
-             (setq location (the fixnum (+ location 1)))
-             (when (= location size)
-               (setq location 0))
-             (when (= location primary)
-               (dolist (entry overflow)
-                 (when (eq (car entry) ,wrapper)
-                   (return-from search nil)))
-               (go ,miss-label))))))
-
-(defmacro get-cache-vector-lock-count (cache-vector)
-  `(let ((lock-count (cache-vector-lock-count ,cache-vector)))
-     (unless (typep lock-count 'fixnum)
-       (error "My cache got freed somehow."))
-     (the fixnum lock-count)))
-
-(defun emit-1-t-dlap (wrapper miss-label value)
-  `(let ((primary ,(emit-1-wrapper-compute-primary-cache-location wrapper
-                                                                  miss-label))
-         (initial-lock-count (get-cache-vector-lock-count cache-vector)))
-     (declare (fixnum primary initial-lock-count))
-     (let ((location primary))
-       (declare (fixnum location))
-       (block search
-         (loop (when (eq ,wrapper (cache-vector-ref cache-vector location))
-                 (setq ,value (cache-vector-ref cache-vector (1+ location)))
-                 (return-from search nil))
-               (setq location (the fixnum (+ location 2)))
-               (when (= location size)
-                 (setq location 0))
-               (when (= location primary)
-                 (dolist (entry overflow)
-                   (when (eq (car entry) ,wrapper)
-                     (setq ,value (cdr entry))
-                     (return-from search nil)))
-                 (go ,miss-label))))
-       (unless (= initial-lock-count
-                  (get-cache-vector-lock-count cache-vector))
-         (go ,miss-label)))))
-
-(defun emit-greater-than-1-dlap (wrappers miss-label value)
-  (declare (type list wrappers))
-  (let ((cache-line-size (compute-line-size (+ (length wrappers)
-                                               (if value 1 0)))))
-    `(let ((primary 0)
-           (size-1 (the fixnum (- size 1))))
-       (declare (fixnum primary size-1))
-       ,(emit-n-wrapper-compute-primary-cache-location wrappers miss-label)
-       (let ((initial-lock-count (get-cache-vector-lock-count cache-vector)))
-         (declare (fixnum initial-lock-count))
-         (let ((location primary)
-               (next-location 0))
-           (declare (fixnum location next-location))
-           (block search
-             (loop (setq next-location
-                         (the fixnum (+ location ,cache-line-size)))
-                   (when (and ,@(mapcar
-                                 (lambda (wrapper)
-                                   `(eq ,wrapper
-                                        (cache-vector-ref
-                                         cache-vector
-                                         (setq location
-                                               (the fixnum (+ location 1))))))
-                                 wrappers))
-                     ,@(when value
-                         `((setq location (the fixnum (+ location 1)))
-                           (setq ,value (cache-vector-ref cache-vector
-                                                          location))))
-                     (return-from search nil))
-                   (setq location next-location)
-                   (when (= location size-1)
-                     (setq location 0))
-                   (when (= location primary)
-                     (dolist (entry overflow)
-                       (let ((entry-wrappers (car entry)))
-                         (when (and ,@(mapcar (lambda (wrapper)
-                                                `(eq ,wrapper
-                                                     (pop entry-wrappers)))
-                                              wrappers))
-                           ,@(when value
-                               `((setq ,value (cdr entry))))
-                           (return-from search nil))))
-                     (go ,miss-label))))
-           (unless (= initial-lock-count
-                      (get-cache-vector-lock-count cache-vector))
-             (go ,miss-label)))))))
-
-(defun emit-1-wrapper-compute-primary-cache-location (wrapper miss-label)
-  `(let ((wrapper-cache-no (layout-clos-hash ,wrapper)))
-     (declare (fixnum wrapper-cache-no))
-     (when (zerop wrapper-cache-no) (go ,miss-label))
-     ,(let ((form `(logand mask wrapper-cache-no)))
-        `(the fixnum ,form))))
-
-(defun emit-n-wrapper-compute-primary-cache-location (wrappers miss-label)
-  (declare (type list wrappers))
-  ;; This returns 1 less that the actual location.
-  `(progn
-     ,@(let ((adds 0) (len (length wrappers)))
-         (declare (fixnum adds len))
-         (mapcar (lambda (wrapper)
-                   `(let ((wrapper-cache-no (layout-clos-hash ,wrapper)))
-                      (declare (fixnum wrapper-cache-no))
-                      (when (zerop wrapper-cache-no) (go ,miss-label))
-                      (setq primary (the fixnum (+ primary wrapper-cache-no)))
-                      ,@(progn
-                          (incf adds)
-                          (when (or (zerop (mod adds
-                                                wrapper-cache-number-adds-ok))
-                                    (eql adds len))
-                            `((setq primary
-                                    ,(let ((form `(logand primary mask)))
-                                       `(the fixnum ,form))))))))
-                 wrappers))))
-
 ;;; CMU17 (and SBCL) note: Since STD-INSTANCE-P is weakened in the
 ;;; CMU/SBCL approach of using funcallable instances, that branch may
 ;;; run on non-pcl instances (structures). The result will be the
 ;;; "slots" will be whatever the first slot is, but will be ignored.
 ;;; Similarly, FSC-INSTANCE-P returns true on funcallable structures
 ;;; as well as PCL fins.
-(defun emit-fetch-wrapper (metatype argument miss-label &optional slot)
+(defun emit-fetch-wrapper (metatype argument miss-tag &optional slot)
   (ecase metatype
     ((standard-instance)
      `(cond ((std-instance-p ,argument)
              ,@(when slot `((setq ,slot (fsc-instance-slots ,argument))))
              (fsc-instance-wrapper ,argument))
             (t
-             (go ,miss-label))))
+             (go ,miss-tag))))
     ;; Sep92 PCL used to distinguish between some of these cases (and
     ;; spuriously exclude others).  Since in SBCL
     ;; WRAPPER-OF/LAYOUT-OF/BUILT-IN-OR-STRUCTURE-WRAPPER are all