Cache overload resolution on sbcl
Annotate for file /src/sb-optimize.lisp
2009-07-08 tobias 1 (in-package :smoke)
14:56:52 ' 2
' 3 (declaim (optimize (debug 3)))
' 4
' 5 (defmacro catch-try ((tag &optional catch-result) catch-form &body body)
' 6 "Catch TAG in the BODY forms. When TAG is throw CATCH-RESULT is bound
' 7 to the thrown values and result of CATCH-FORM is returned. Otherwise
' 8 the result of BODY is returned and CATCH-FORM is not evaluated."
' 9 (flet ((catch-block (tag return-block body)
' 10 `(catch ,tag
' 11 (return-from ,return-block
' 12 ,@body))))
' 13 (let ((return-block (gensym)))
' 14 `(block ,return-block
' 15 ,(if catch-result
' 16 `(let ((,catch-result ,(catch-block tag return-block body)))
' 17 ,catch-form)
' 18 `(progn ,(catch-block tag return-block body)
' 19 ,catch-form))))))
' 20
' 21 (defun type-specifier (lvar)
' 22 (let ((type (sb-kernel:type-specifier (sb-c::lvar-type lvar))))
' 23 (if (subtypep type 'smoke-standard-object)
' 24 (find-class type)
' 25 type)))
' 26
' 27
' 28 (defun give-up-transform (&rest args)
' 29 (apply #'sb-c::give-up-ir1-transform args))
' 30
' 31 (defmacro define-transform (name lambda-list &body body)
' 32 `(sb-c:deftransform ,name (,lambda-list)
' 33 ,@body))
' 34
' 35 (defmacro define-known (name)
' 36 `(sb-c:defknown ,name * *))
' 37
' 38 (defun method-form (method)
' 39 `(make-smoke-method
' 40 :id ,(id method)
' 41 :smoke (eval ,(get-smoke-variable-for-pointer
' 42 (smoke method)))))
' 43
' 44 (defun sequence-form (sequence arguments)
' 45 (mapcar #'(lambda (sequence argument)
' 46 (if (symbolp sequence)
' 47 `(,sequence ,argument)
' 48 `(,(first sequence) ,argument ,@(rest sequence))))
' 49 sequence arguments))
' 50
' 51
' 52 (defmacro define-resolve-at-compile-time (gf-name)
' 53 `(eval-when (:compile-toplevel :load-toplevel :execute)
' 54 (define-known ,gf-name)
' 55 (sb-c:defoptimizer (,gf-name derive-type) ((object &rest args))
' 56 (catch-try ('unspecific-type) sb-c::*wild-type*
' 57 (let ((method (find-best-viable-function-using-types
' 58 ,(name (fdefinition gf-name))
' 59 (mapcar #'type-specifier args) (type-specifier object))))
' 60 (if (and method (class-p (return-type method)))
' 61 (sb-kernel:single-value-specifier-type
' 62 (find-smoke-class (get-class (return-type method))))
' 63 sb-c::*wild-type*))))
' 64 (define-transform ,gf-name (object &rest args)
' 65 (when (null args)
' 66 (give-up-transform "No arguments."))
' 67 (catch-try ('unspecific-type reason)
' 68 (give-up-transform "Could not resolve overload at compile time: ~A" reason)
' 69 (multiple-value-bind (method sequence)
' 70 (find-best-viable-function-using-types
' 71 ,(name (fdefinition gf-name))
' 72 (mapcar #'type-specifier args)
' 73 (type-specifier object))
' 74 (let ((argument-names (make-gensym-list (length args))))
' 75 (when (null method)
' 76 (give-up-transform "No applicable method."))
' 77 (if (static-p method)
' 78 `(s-call ,(method-form method)
' 79 (null-pointer)
' 80 (list ,@(sequence-form
' 81 sequence args)))
' 82 `(lambda (object ,@argument-names)
' 83 (s-call ,(method-form method)
2009-07-08 tobias 84 ,(if (eql (type-specifier object)
20:41:19 ' 85 (find-smoke-class (get-class method)))
' 86 `(pointer object)
' 87 `(cast object
' 88 (find-class (quote ,(class-name
' 89 (find-smoke-class
' 90 (get-class method)))))))
2009-07-08 tobias 91 (list ,@(sequence-form
14:56:52 ' 92 sequence argument-names)))))))))))
2009-09-01 tobias 93
2010-02-20 tobias 94 ;;; Cache overload resolution / method lookup
17:24:36 ' 95
' 96 ;;; FIXME the cached lookup should be faster
2009-09-01 tobias 97 ;;;
2010-02-20 tobias 98 ;;; cache return value conversion
17:24:36 ' 99 ;;;
' 100 ;;; Using the gf symbol instead of the method name would be better,
' 101 ;;; althoug we would have to invent one for constructors.
' 102 ;;;
' 103 ;;; Since the -using-types stuff was intended for for compile time
' 104 ;;; expansion it is not that well suited for this. i.e. passing
' 105 ;;; closures would be better than the actual syntax.
' 106 ;;;
' 107 ;;; For qt.tests the uncached calls make up 30 % of all calls.
' 108 ;;; qt.examples:colliding-mice (run for ~1 min) gets 20 % uncached
' 109 ;;; calls and qt.examples:class-browser get 10 %. (20 February 2010)
2009-09-01 tobias 110
2010-02-20 tobias 111 (sb-int:defun-cached (find-best-viable-function-using-layouts-cached
2009-09-01 tobias 112 :hash-function (lambda (name arguments
11:44:21 ' 113 class const-p)
' 114 (declare (string name)
' 115 (list arguments)
2010-02-20 tobias 116 (sb-c::layout class)
2009-09-01 tobias 117 (boolean const-p))
11:44:21 ' 118 (logand
' 119 (logxor
' 120 (sxhash name)
2010-02-20 tobias 121 (the fixnum
17:24:36 ' 122 (reduce
' 123 #'logxor
' 124 (mapcar #'sb-c::layout-clos-hash
' 125 arguments)))
2009-09-01 tobias 126 (sxhash class)
11:44:21 ' 127 (sxhash const-p))
' 128 #x1FF))
' 129 :hash-bits 9)
' 130 ((name equal) (arguments equal) (class eq) (const-p eq))
' 131 (declare (optimize (speed 3))
' 132 (inline find-best-viable-function-using-types))
' 133 (multiple-value-bind (method conversion-sequence)
2010-02-20 tobias 134 (find-best-viable-function-using-types
17:24:36 ' 135 name (mapcar #'sb-pcl::wrapper-class* arguments)
' 136 class const-p)
2009-09-01 tobias 137 (list method (mapcar #'(lambda (s)
11:44:21 ' 138 (if (symbolp s)
' 139 (fdefinition s)
' 140 #'(lambda (x)
2010-02-20 tobias 141 (declare (optimize (speed 3)))
2009-09-01 tobias 142 (funcall (fdefinition (first s))
11:44:21 ' 143 x
2010-02-20 tobias 144 (eval (second s))))))
2009-09-01 tobias 145 conversion-sequence))))
2010-02-20 tobias 146
2009-09-01 tobias 147 (declaim (inline find-best-viable-function-cached))
11:44:21 ' 148 (defun find-best-viable-function-cached (name arguments class const-p)
' 149 (declare (optimize (speed 3)))
' 150 (catch 'unspecific-type
' 151 (return-from find-best-viable-function-cached
' 152 (values-list
2010-02-20 tobias 153 (find-best-viable-function-using-layouts-cached
2009-09-01 tobias 154 name
2010-02-20 tobias 155 (mapcar #'(lambda (o) (sb-c::layout-of o)) arguments)
2009-09-01 tobias 156 class
11:44:21 ' 157 const-p))))
' 158 (find-best-viable-function name arguments class const-p))
' 159