1.0.31.9: some PCL micro-optimizations
[sbcl.git] / src / pcl / methods.lisp
index 79ac11b..30ceedd 100644 (file)
 \f
 (defmethod generic-function-argument-precedence-order
     ((gf standard-generic-function))
-  (aver (eq *boot-state* 'complete))
+  (aver (eq **boot-state** 'complete))
   (loop with arg-info = (gf-arg-info gf)
         with lambda-list = (arg-info-lambda-list arg-info)
         for argument-position in (arg-info-precedence arg-info)
                (gf-lambda-list (generic-function-lambda-list gf))
                (tfun (constantly t))
                keysp)
-          (multiple-value-bind
-              (gf.required gf.optional gf.rest ignore gf.allowp)
-              (%split-arglist gf-lambda-list)
-            (declare (ignore ignore))
-            (setf (info :function :type name)
-                  (specifier-type
-                   `(function
-                     (,@(mapcar tfun gf.required)
-                        ,@(if gf.optional
-                              `(&optional ,@(mapcar tfun gf.optional)))
-                        ,@(if gf.rest
-                              `(&rest t))
-                        ,@(let ((all-keys
-                                 (mapcar
-                                  (lambda (x)
-                                    (list x t))
-                                  (remove-duplicates
-                                   (mapcan #'function-keywords methods)))))
-                            (when all-keys
-                              (setq keysp t)
-                              `(&key ,@all-keys)))
-                        ,@(if (and keysp gf.allowp)
+          (multiple-value-bind (gf.required gf.optional gf.restp gf.rest
+                                            gf.keyp gf.keys gf.allowp)
+              (parse-lambda-list gf-lambda-list)
+            (declare (ignore gf.rest))
+            ;; 7.6.4 point 5 probably entails that if any method says
+            ;; &allow-other-keys then the gf should be construed to
+            ;; accept any key.
+            (let ((allowp (or gf.allowp
+                              (find '&allow-other-keys methods
+                                    :test #'find
+                                    :key #'method-lambda-list))))
+              (setf (info :function :type name)
+                    (specifier-type
+                     `(function
+                       (,@(mapcar tfun gf.required)
+                          ,@(if gf.optional
+                                `(&optional ,@(mapcar tfun gf.optional)))
+                          ,@(if gf.restp
+                                `(&rest t))
+                          ,@(when gf.keyp
+                              (let ((all-keys
+                                     (mapcar
+                                      (lambda (x)
+                                        (list x t))
+                                      (remove-duplicates
+                                       (nconc
+                                        (mapcan #'function-keywords methods)
+                                        (mapcar #'keywordicate gf.keys))))))
+                                (when all-keys
+                                  (setq keysp t)
+                                  `(&key ,@all-keys))))
+                          ,@(when (and (not keysp) allowp)
+                              `(&key))
+                          ,@(when allowp
                               `(&allow-other-keys)))
-                     *))
-                  (info :function :where-from name) :defined-method
-                  (gf-info-needs-update gf) nil)))))
+                       *))
+                    (info :function :where-from name) :defined-method
+                    (gf-info-needs-update gf) nil))))))
     (values)))
 \f
 (defun compute-applicable-methods-function (generic-function arguments)
 (defvar *std-cam-methods* nil)
 
 (defun compute-applicable-methods-emf (generic-function)
-  (if (eq *boot-state* 'complete)
+  (if (eq **boot-state** 'complete)
       (let* ((cam (gdefinition 'compute-applicable-methods))
              (cam-methods (compute-applicable-methods-using-types
                            cam (list `(eql ,generic-function) t))))
       (eq gf #'(setf slot-value-using-class))
       (eq gf #'slot-boundp-using-class)))
 
-(let (po-cache)
+(let (initial-print-object-cache)
   (defmethod compute-discriminating-function ((gf standard-generic-function))
     (let ((dfun-state (slot-value gf 'dfun-state)))
       (when (special-case-for-compute-discriminating-function-p gf)
               (cond ((/= nkeys 1)
                      ;; KLUDGE: someone has defined a method
                      ;; specialized on the second argument: punt.
-                     (setf po-cache nil)
+                     (setf initial-print-object-cache nil)
                      (make-initial-dfun gf))
-                    (po-cache
+                    (initial-print-object-cache
                      (multiple-value-bind (dfun cache info)
-                         (make-caching-dfun gf po-cache)
+                         (make-caching-dfun gf (copy-cache initial-print-object-cache))
                        (set-dfun gf dfun cache info)))
                     ;; the relevant PRINT-OBJECT methods get defined
                     ;; late, by delayed DEF!METHOD.  We mustn't cache
                     (t (multiple-value-bind (dfun cache info)
                            (make-final-dfun-internal
                             gf
-                            (list (list (find-class 'sb-kernel::control-stack-exhausted))
-                                  (list (find-class 'sb-kernel::heap-exhausted-error))
-                                  (list (find-class 'restart))))
-                         (setq po-cache cache)
-                         (set-dfun gf dfun cache info))))))
+                            (mapcar (lambda (x) (list (find-class x)))
+                                    '(sb-kernel::control-stack-exhausted
+                                      sb-kernel::binding-stack-exhausted
+                                      sb-kernel::alien-stack-exhausted
+                                      sb-kernel::heap-exhausted-error
+                                      restart)))
+                         (setq initial-print-object-cache cache)
+                         (set-dfun gf dfun (copy-cache cache) info))))))
            ((gf-precompute-dfun-and-emf-p (slot-value gf 'arg-info))
             (make-final-dfun gf))
            (t
             (make-initial-dfun gf))))
         (function dfun-state)
         (cons (car dfun-state))))))
-
-(defmethod update-gf-dfun ((class std-class) gf)
-  (let ((*new-class* class)
-        (arg-info (gf-arg-info gf)))
-    (cond
-      ((special-case-for-compute-discriminating-function-p gf))
-      ((gf-precompute-dfun-and-emf-p arg-info)
-       (multiple-value-bind (dfun cache info)
-           (make-final-dfun-internal gf)
-         (update-dfun gf dfun cache info))))))
 \f
 (defmethod (setf class-name) (new-value class)
   (let ((classoid (wrapper-classoid (class-wrapper class))))
 \f
 (defmethod function-keywords ((method standard-method))
   (multiple-value-bind (nreq nopt keysp restp allow-other-keys-p
-                        keywords keyword-parameters)
+                        keywords)
       (analyze-lambda-list (if (consp method)
                                (early-method-lambda-list method)
                                (method-lambda-list method)))
-    (declare (ignore nreq nopt keysp restp keywords))
+    (declare (ignore nreq nopt keysp restp))
     (values keywords allow-other-keys-p)))
 
 (defmethod function-keyword-parameters ((method standard-method))