sb-introspect:find-definition-sources-by-name: find VOPs by name.
[sbcl.git] / contrib / sb-introspect / introspect.lisp
1 ;;; introspection library
2
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5 ;;;;
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
11
12 ;;; For the avoidance of doubt, the exported interface is the supported
13 ;;; interface. Anything else is internal, though you're welcome to argue a
14 ;;; case for exporting it.
15
16 ;;; If you steal the code from this file to cut and paste into your
17 ;;; own project, there will be much wailing and gnashing of teeth.
18 ;;; Your teeth.  If need be, we'll kick them for you.  This is a
19 ;;; contrib, we're allowed to look in internals.  You're an
20 ;;; application programmer, and are not.
21
22 ;;; TODO
23 ;;; 1) structs don't have within-file location info.  problem for the
24 ;;;   structure itself, accessors, the copier and the predicate
25 ;;; 3) error handling.  Signal random errors, or handle and resignal 'our'
26 ;;;   error, or return NIL?
27 ;;; 4) FIXMEs
28
29 (defpackage :sb-introspect
30   (:use "CL")
31   (:export "ALLOCATION-INFORMATION"
32            "FUNCTION-ARGLIST"
33            "FUNCTION-LAMBDA-LIST"
34            "FUNCTION-TYPE"
35            "DEFTYPE-LAMBDA-LIST"
36            "VALID-FUNCTION-NAME-P"
37            "FIND-DEFINITION-SOURCE"
38            "FIND-DEFINITION-SOURCES-BY-NAME"
39            "DEFINITION-SOURCE"
40            "DEFINITION-SOURCE-PATHNAME"
41            "DEFINITION-SOURCE-FORM-PATH"
42            "DEFINITION-SOURCE-CHARACTER-OFFSET"
43            "DEFINITION-SOURCE-FILE-WRITE-DATE"
44            "DEFINITION-SOURCE-PLIST"
45            "DEFINITION-NOT-FOUND" "DEFINITION-NAME"
46            "FIND-FUNCTION-CALLEES"
47            "FIND-FUNCTION-CALLERS"
48            "MAP-ROOT"
49            "WHO-BINDS"
50            "WHO-CALLS"
51            "WHO-REFERENCES"
52            "WHO-SETS"
53            "WHO-MACROEXPANDS"
54            "WHO-SPECIALIZES-DIRECTLY"
55            "WHO-SPECIALIZES-GENERALLY"))
56
57 (in-package :sb-introspect)
58
59 ;;;; Internal interface for SBCL debug info
60
61 ;;; Here are some tutorial-style type definitions to help understand
62 ;;; the internal SBCL debugging data structures we're using. The
63 ;;; commentary is based on CMUCL's debug internals manual.
64 ;;;
65 (deftype debug-info ()
66   "Structure containing all the debug information related to a function.
67 Function objects reference debug-infos which in turn reference
68 debug-sources and so on."
69   'sb-c::compiled-debug-info)
70
71 (deftype debug-source ()
72   "Debug sources describe where to find source code.
73 For example, the debug source for a function compiled from a file will
74 include the pathname of the file and the position of the definition."
75   'sb-c::debug-source)
76
77 (deftype debug-function ()
78   "Debug function represent static compile-time information about a function."
79   'sb-c::compiled-debug-fun)
80
81 (declaim (ftype (function (function) debug-info) function-debug-info))
82 (defun function-debug-info (function)
83   (let* ((function-object (sb-kernel::%fun-fun function))
84          (function-header (sb-kernel:fun-code-header function-object)))
85     (sb-kernel:%code-debug-info function-header)))
86
87 (declaim (ftype (function (function) debug-source) function-debug-source))
88 (defun function-debug-source (function)
89   (debug-info-source (function-debug-info function)))
90
91 (declaim (ftype (function (debug-info) debug-source) debug-info-source))
92 (defun debug-info-source (debug-info)
93   (sb-c::debug-info-source debug-info))
94
95 (declaim (ftype (function (debug-info) debug-function) debug-info-debug-function))
96 (defun debug-info-debug-function (debug-info)
97   (elt (sb-c::compiled-debug-info-fun-map debug-info) 0))
98
99 (defun valid-function-name-p (name)
100   "True if NAME denotes a valid function name, ie. one that can be passed to
101 FBOUNDP."
102   (and (sb-int:valid-function-name-p name) t))
103
104 ;;;; Finding definitions
105
106 (defstruct definition-source
107   ;; Pathname of the source file that the definition was compiled from.
108   ;; This is null if the definition was not compiled from a file.
109   (pathname nil :type (or null pathname))
110   ;; Source-path of the definition within the file.
111   ;; This may be incomplete depending on the debug level at which the
112   ;; source was compiled.
113   (form-path '() :type list)
114   ;; Character offset of the top-level-form containing the definition.
115   ;; This corresponds to the first element of form-path.
116   (character-offset nil :type (or null integer))
117   ;; File-write-date of the source file when compiled.
118   ;; Null if not compiled from a file.
119   (file-write-date nil :type (or null integer))
120   ;; plist from WITH-COMPILATION-UNIT
121   (plist nil)
122   ;; Any extra metadata that the caller might be interested in. For
123   ;; example the specializers of the method whose definition-source this
124   ;; is.
125   (description nil :type list))
126
127 (defun vop-sources-from-fun-templates (name)
128   (let ((fun-info (sb-int:info :function :info name)))
129     (when fun-info
130       (loop for vop in (sb-c::fun-info-templates fun-info)
131             for source = (find-definition-source
132                           (sb-c::vop-info-generator-function vop))
133             do (setf (definition-source-description source)
134                      (list (sb-c::template-name vop)
135                            (sb-c::template-note vop)))
136             collect source))))
137
138 (defun find-vop-source (name)
139   (let* ((templates (vop-sources-from-fun-templates name))
140          (vop (gethash name sb-c::*backend-template-names*))
141          (source (and vop
142                       (find-definition-source
143                        (sb-c::vop-info-generator-function vop)))))
144     (when source
145       (setf (definition-source-description source)
146             (list name)))
147     (if source
148         (cons source templates)
149         templates)))
150
151 (defun find-definition-sources-by-name (name type)
152   "Returns a list of DEFINITION-SOURCEs for the objects of type TYPE
153 defined with name NAME. NAME may be a symbol or a extended function
154 name. Type can currently be one of the following:
155
156    (Public)
157    :CLASS
158    :COMPILER-MACRO
159    :CONDITION
160    :CONSTANT
161    :FUNCTION
162    :GENERIC-FUNCTION
163    :MACRO
164    :METHOD
165    :METHOD-COMBINATION
166    :PACKAGE
167    :SETF-EXPANDER
168    :STRUCTURE
169    :SYMBOL-MACRO
170    :TYPE
171    :VARIABLE
172
173    (Internal)
174    :OPTIMIZER
175    :SOURCE-TRANSFORM
176    :TRANSFORM
177    :VOP
178
179 If an unsupported TYPE is requested, the function will return NIL.
180 "
181   (flet ((listify (x)
182            (if (listp x)
183                x
184                (list x)))
185          (get-class (name)
186            (and (symbolp name)
187                 (find-class name nil)))
188          (real-fdefinition (name)
189            ;; for getting the real function object, even if the
190            ;; function is being profiled
191            (let ((profile-info (gethash name sb-profile::*profiled-fun-name->info*)))
192              (if profile-info
193                  (sb-profile::profile-info-encapsulated-fun profile-info)
194                  (fdefinition name)))))
195     (listify
196      (case type
197        ((:variable)
198         (when (and (symbolp name)
199                    (eq (sb-int:info :variable :kind name) :special))
200           (translate-source-location (sb-int:info :source-location type name))))
201        ((:constant)
202         (when (and (symbolp name)
203                    (eq (sb-int:info :variable :kind name) :constant))
204           (translate-source-location (sb-int:info :source-location type name))))
205        ((:symbol-macro)
206         (when (and (symbolp name)
207                    (eq (sb-int:info :variable :kind name) :macro))
208           (translate-source-location (sb-int:info :source-location type name))))
209        ((:macro)
210         (when (and (symbolp name)
211                    (macro-function name))
212           (find-definition-source (macro-function name))))
213        ((:compiler-macro)
214         (when (compiler-macro-function name)
215           (find-definition-source (compiler-macro-function name))))
216        ((:function :generic-function)
217         (when (and (fboundp name)
218                    (or (not (symbolp name))
219                        (not (macro-function name))
220                        (special-operator-p name)))
221           (let ((fun (real-fdefinition name)))
222             (when (eq (not (typep fun 'generic-function))
223                       (not (eq type :generic-function)))
224               (find-definition-source fun)))))
225        ((:type)
226         ;; Source locations for types are saved separately when the expander
227         ;; is a closure without a good source-location.
228         (let ((loc (sb-int:info :type :source-location name)))
229           (if loc
230               (translate-source-location loc)
231               (let ((expander-fun (sb-int:info :type :expander name)))
232                 (when expander-fun
233                   (find-definition-source expander-fun))))))
234        ((:method)
235         (when (fboundp name)
236           (let ((fun (real-fdefinition name)))
237            (when (typep fun 'generic-function)
238              (loop for method in (sb-mop::generic-function-methods
239                                   fun)
240                 for source = (find-definition-source method)
241                 when source collect source)))))
242        ((:setf-expander)
243         (when (and (consp name)
244                    (eq (car name) 'setf))
245           (setf name (cadr name)))
246         (let ((expander (or (sb-int:info :setf :inverse name)
247                             (sb-int:info :setf :expander name))))
248           (when expander
249             (sb-introspect:find-definition-source (if (symbolp expander)
250                                                       (symbol-function expander)
251                                                       expander)))))
252        ((:structure)
253         (let ((class (get-class name)))
254           (if class
255               (when (typep class 'sb-pcl::structure-class)
256                 (find-definition-source class))
257               (when (sb-int:info :typed-structure :info name)
258                 (translate-source-location
259                  (sb-int:info :source-location :typed-structure name))))))
260        ((:condition :class)
261         (let ((class (get-class name)))
262           (when (and class
263                      (not (typep class 'sb-pcl::structure-class)))
264             (when (eq (not (typep class 'sb-pcl::condition-class))
265                       (not (eq type :condition)))
266               (find-definition-source class)))))
267        ((:method-combination)
268         (let ((combination-fun
269                (find-method #'sb-mop:find-method-combination
270                             nil
271                             (list (find-class 'generic-function)
272                                   (list 'eql name)
273                                   t)
274                             nil)))
275           (when combination-fun
276             (find-definition-source combination-fun))))
277        ((:package)
278         (when (symbolp name)
279           (let ((package (find-package name)))
280             (when package
281               (find-definition-source package)))))
282        ;; TRANSFORM and OPTIMIZER handling from swank-sbcl
283        ((:transform)
284         (when (symbolp name)
285           (let ((fun-info (sb-int:info :function :info name)))
286             (when fun-info
287               (loop for xform in (sb-c::fun-info-transforms fun-info)
288                     for source = (find-definition-source
289                                   (sb-c::transform-function xform))
290                     for typespec = (sb-kernel:type-specifier
291                                     (sb-c::transform-type xform))
292                     for note = (sb-c::transform-note xform)
293                     do (setf (definition-source-description source)
294                              (if (consp typespec)
295                                  (list (second typespec) note)
296                                  (list note)))
297                     collect source)))))
298        ((:optimizer)
299         (when (symbolp name)
300           (let ((fun-info (sb-int:info :function :info name)))
301             (when fun-info
302               (let ((otypes '((sb-c::fun-info-derive-type . sb-c:derive-type)
303                               (sb-c::fun-info-ltn-annotate . sb-c:ltn-annotate)
304                               (sb-c::fun-info-ltn-annotate . sb-c:ltn-annotate)
305                               (sb-c::fun-info-optimizer . sb-c:optimizer))))
306                 (loop for (reader . name) in otypes
307                       for fn = (funcall reader fun-info)
308                       when fn collect
309                       (let ((source (find-definition-source fn)))
310                         (setf (definition-source-description source)
311                               (list name))
312                         source)))))))
313        ((:vop)
314         (when (symbolp name)
315           (find-vop-source name)))
316        ((:source-transform)
317         (when (symbolp name)
318           (let ((transform-fun (sb-int:info :function :source-transform name)))
319             (when transform-fun
320               (sb-introspect:find-definition-source transform-fun)))))
321        (t
322         nil)))))
323
324 (defun find-definition-source (object)
325   (typecase object
326     ((or sb-pcl::condition-class sb-pcl::structure-class)
327      (let ((classoid (sb-impl::find-classoid (class-name object))))
328        (when classoid
329          (let ((layout (sb-impl::classoid-layout classoid)))
330            (when layout
331              (translate-source-location
332               (sb-kernel::layout-source-location layout)))))))
333     (method-combination
334      (car
335       (find-definition-sources-by-name
336        (sb-pcl::method-combination-type-name object) :method-combination)))
337     (package
338      (translate-source-location (sb-impl::package-source-location object)))
339     (class
340      (translate-source-location (sb-pcl::definition-source object)))
341     ;; Use the PCL definition location information instead of the function
342     ;; debug-info for methods and generic functions. Sometimes the
343     ;; debug-info would point into PCL internals instead of the proper
344     ;; location.
345     (generic-function
346      (let ((source (translate-source-location
347                     (sb-pcl::definition-source object))))
348        (when source
349          (setf (definition-source-description source)
350                (list (sb-mop:generic-function-lambda-list object))))
351        source))
352     (method
353      (let ((source (translate-source-location
354                     (sb-pcl::definition-source object))))
355        (when source
356          (setf (definition-source-description source)
357                (append (method-qualifiers object)
358                        (if (sb-mop:method-generic-function object)
359                            (sb-pcl::unparse-specializers
360                             (sb-mop:method-generic-function object)
361                             (sb-mop:method-specializers object))
362                            (sb-mop:method-specializers object)))))
363        source))
364     #+sb-eval
365     (sb-eval:interpreted-function
366      (let ((source (translate-source-location
367                     (sb-eval:interpreted-function-source-location object))))
368        source))
369     (function
370      (cond ((struct-accessor-p object)
371             (find-definition-source
372              (struct-accessor-structure-class object)))
373            ((struct-predicate-p object)
374             (find-definition-source
375              (struct-predicate-structure-class object)))
376            ((struct-copier-p object)
377             (find-definition-source
378              (struct-copier-structure-class object)))
379            (t
380             (find-function-definition-source object))))
381     ((or condition standard-object structure-object)
382      (find-definition-source (class-of object)))
383     (t
384      (error "Don't know how to retrieve source location for a ~S"
385             (type-of object)))))
386
387 (defun find-function-definition-source (function)
388   (let* ((debug-info (function-debug-info function))
389          (debug-source (debug-info-source debug-info))
390          (debug-fun (debug-info-debug-function debug-info))
391          (tlf (if debug-fun (sb-c::compiled-debug-fun-tlf-number debug-fun))))
392     (make-definition-source
393      :pathname
394      ;; KLUDGE: at the moment, we don't record the correct toplevel
395      ;; form number for forms processed by EVAL (including EVAL-WHEN
396      ;; :COMPILE-TOPLEVEL).  Until that's fixed, don't return a
397      ;; DEFINITION-SOURCE with a pathname.  (When that's fixed, take
398      ;; out the (not (debug-source-form ...)) test.
399      (when (stringp (sb-c::debug-source-namestring debug-source))
400        (parse-namestring (sb-c::debug-source-namestring debug-source)))
401      :character-offset
402      (if tlf
403          (elt (sb-c::debug-source-start-positions debug-source) tlf))
404      ;; Unfortunately there is no proper source path available in the
405      ;; debug-source. FIXME: We could use sb-di:code-locations to get
406      ;; a full source path. -luke (12/Mar/2005)
407      :form-path (if tlf (list tlf))
408      :file-write-date (sb-c::debug-source-created debug-source)
409      :plist (sb-c::debug-source-plist debug-source))))
410
411 (defun translate-source-location (location)
412   (if location
413       (make-definition-source
414        :pathname (let ((n (sb-c:definition-source-location-namestring location)))
415                    (when n
416                      (parse-namestring n)))
417        :form-path
418        (let ((number (sb-c:definition-source-location-toplevel-form-number
419                          location)))
420          (when number
421            (list number)))
422        :plist (sb-c:definition-source-location-plist location))
423       (make-definition-source)))
424
425 ;;; This is kludgey.  We expect these functions (the underlying functions,
426 ;;; not the closures) to be in static space and so not move ever.
427 ;;; FIXME It's also possibly wrong: not all structures use these vanilla
428 ;;; accessors, e.g. when the :type option is used
429 (defvar *struct-slotplace-reader*
430   (sb-vm::%simple-fun-self #'definition-source-pathname))
431 (defvar *struct-slotplace-writer*
432   (sb-vm::%simple-fun-self #'(setf definition-source-pathname)))
433 (defvar *struct-predicate*
434   (sb-vm::%simple-fun-self #'definition-source-p))
435 (defvar *struct-copier*
436   (sb-vm::%simple-fun-self #'copy-definition-source))
437
438 (defun struct-accessor-p (function)
439   (let ((self (sb-vm::%simple-fun-self function)))
440     ;; FIXME there are other kinds of struct accessor.  Fill out this list
441     (member self (list *struct-slotplace-reader*
442                        *struct-slotplace-writer*))))
443
444 (defun struct-copier-p (function)
445   (let ((self (sb-vm::%simple-fun-self function)))
446     ;; FIXME there may be other structure copier functions
447     (member self (list *struct-copier*))))
448
449 (defun struct-predicate-p (function)
450   (let ((self (sb-vm::%simple-fun-self function)))
451     ;; FIXME there may be other structure predicate functions
452     (member self (list *struct-predicate*))))
453
454 (sb-int:define-deprecated-function :late "1.0.24.5" function-arglist function-lambda-list
455     (function)
456   (function-lambda-list function))
457
458 (defun function-lambda-list (function)
459   "Describe the lambda list for the extended function designator FUNCTION.
460 Works for special-operators, macros, simple functions, interpreted functions,
461 and generic functions. Signals an error if FUNCTION is not a valid extended
462 function designator."
463   (cond ((valid-function-name-p function)
464          (function-lambda-list (or (and (symbolp function)
465                                         (macro-function function))
466                                    (fdefinition function))))
467         ((typep function 'generic-function)
468          (sb-pcl::generic-function-pretty-arglist function))
469         #+sb-eval
470         ((typep function 'sb-eval:interpreted-function)
471          (sb-eval:interpreted-function-lambda-list function))
472         (t
473          (sb-kernel:%simple-fun-arglist (sb-kernel:%fun-fun function)))))
474
475 (defun deftype-lambda-list (typespec-operator)
476   "Returns the lambda list of TYPESPEC-OPERATOR as first return
477 value, and a flag whether the arglist could be found as second
478 value."
479   (check-type typespec-operator symbol)
480   (case (sb-int:info :type :kind typespec-operator)
481     (:defined
482      (sb-int:info :type :lambda-list typespec-operator))
483     (:primitive
484      (let ((translator-fun (sb-int:info :type :translator typespec-operator)))
485        (if translator-fun
486            (values (sb-kernel:%fun-lambda-list translator-fun) t)
487            ;; Some builtin types (e.g. STRING) do not have a
488            ;; translator, but they were actually defined via DEFTYPE
489            ;; in src/code/deftypes-for-target.lisp.
490            (sb-int:info :type :lambda-list typespec-operator))))
491     (t (values nil nil))))
492
493 (defun function-type (function-designator)
494   "Returns the ftype of FUNCTION-DESIGNATOR, or NIL."
495   (flet ((ftype-of (function-designator)
496            (sb-kernel:type-specifier
497             (sb-int:info :function :type function-designator))))
498     (etypecase function-designator
499       (symbol
500        (when (and (fboundp function-designator)
501                   (not (macro-function function-designator))
502                   (not (special-operator-p function-designator)))
503          (ftype-of function-designator)))
504       (cons
505        (when (and (sb-int:legal-fun-name-p function-designator)
506                   (fboundp function-designator))
507          (ftype-of function-designator)))
508       (generic-function
509        (function-type (sb-pcl:generic-function-name function-designator)))
510       (function
511        ;; Give declared type in globaldb priority over derived type
512        ;; because it contains more accurate information e.g. for
513        ;; struct-accessors.
514        (let ((type (function-type (sb-kernel:%fun-name
515                                    (sb-impl::%fun-fun function-designator)))))
516          (if type
517              type
518              (sb-impl::%fun-type function-designator)))))))
519
520 ;;; FIXME: These three are pretty terrible. Can we place have some proper metadata
521 ;;; instead.
522
523 (defun struct-accessor-structure-class (function)
524   (let ((self (sb-vm::%simple-fun-self function)))
525     (cond
526       ((member self (list *struct-slotplace-reader* *struct-slotplace-writer*))
527        (find-class
528         (sb-kernel::classoid-name
529          (sb-kernel::layout-classoid
530           (sb-kernel:%closure-index-ref function 1)))))
531       )))
532
533 (defun struct-copier-structure-class (function)
534   (let ((self (sb-vm::%simple-fun-self function)))
535     (cond
536       ((member self (list *struct-copier*))
537        (find-class
538         (sb-kernel::classoid-name
539          (sb-kernel::layout-classoid
540           (sb-kernel:%closure-index-ref function 0)))))
541       )))
542
543 (defun struct-predicate-structure-class (function)
544   (let ((self (sb-vm::%simple-fun-self function)))
545     (cond
546       ((member self (list *struct-predicate*))
547        (find-class
548         (sb-kernel::classoid-name
549          (sb-kernel::layout-classoid
550           (sb-kernel:%closure-index-ref function 0)))))
551       )))
552
553 ;;;; find callers/callees, liberated from Helmut Eller's code in SLIME
554
555 ;;; This interface is trmendously experimental.
556
557 ;;; For the moment I'm taking the view that FDEFN is an internal
558 ;;; object (one out of one CMUCL developer surveyed didn't know what
559 ;;; they were for), so these routines deal in FUNCTIONs
560
561 ;;; Find callers and callees by looking at the constant pool of
562 ;;; compiled code objects.  We assume every fdefn object in the
563 ;;; constant pool corresponds to a call to that function.  A better
564 ;;; strategy would be to use the disassembler to find actual
565 ;;; call-sites.
566
567 (defun find-function-callees (function)
568   "Return functions called by FUNCTION."
569   (let ((callees '()))
570     (map-code-constants
571      (sb-kernel:fun-code-header function)
572      (lambda (obj)
573        (when (sb-kernel:fdefn-p obj)
574          (push (sb-kernel:fdefn-fun obj)
575                callees))))
576     callees))
577
578
579 (defun find-function-callers (function &optional (spaces '(:read-only :static
580                                                            :dynamic)))
581   "Return functions which call FUNCTION, by searching SPACES for code objects"
582   (let ((referrers '()))
583     (map-caller-code-components
584      function
585      spaces
586      (lambda (code)
587        (let ((entry (sb-kernel:%code-entry-points  code)))
588          (cond ((not entry)
589                 (push (princ-to-string code) referrers))
590                (t
591                 (loop for e = entry then (sb-kernel::%simple-fun-next e)
592                       while e
593                       do (pushnew e referrers)))))))
594     referrers))
595
596 (declaim (inline map-code-constants))
597 (defun map-code-constants (code fn)
598   "Call FN for each constant in CODE's constant pool."
599   (check-type code sb-kernel:code-component)
600   (loop for i from sb-vm:code-constants-offset below
601         (sb-kernel:get-header-data code)
602         do (funcall fn (sb-kernel:code-header-ref code i))))
603
604 (declaim (inline map-allocated-code-components))
605 (defun map-allocated-code-components (spaces fn)
606   "Call FN for each allocated code component in one of SPACES.  FN
607 receives the object and its size as arguments.  SPACES should be a
608 list of the symbols :dynamic, :static, or :read-only."
609   (dolist (space spaces)
610     (sb-vm::map-allocated-objects
611      (lambda (obj header size)
612        (when (= sb-vm:code-header-widetag header)
613          (funcall fn obj size)))
614      space
615      t)))
616
617 (declaim (inline map-caller-code-components))
618 (defun map-caller-code-components (function spaces fn)
619   "Call FN for each code component with a fdefn for FUNCTION in its
620 constant pool."
621   (let ((function (coerce function 'function)))
622     (map-allocated-code-components
623      spaces
624      (lambda (obj size)
625        (declare (ignore size))
626        (map-code-constants
627         obj
628         (lambda (constant)
629           (when (and (sb-kernel:fdefn-p constant)
630                      (eq (sb-kernel:fdefn-fun constant)
631                          function))
632             (funcall fn obj))))))))
633
634 ;;; XREF facility
635
636 (defun get-simple-fun (functoid)
637   (etypecase functoid
638     (sb-kernel::fdefn
639      (get-simple-fun (sb-vm::fdefn-fun functoid)))
640     ((or null sb-impl::funcallable-instance)
641      nil)
642     (function
643      (sb-kernel::%fun-fun functoid))))
644
645 (defun collect-xref (kind-index wanted-name)
646   (let ((ret nil))
647     (dolist (env sb-c::*info-environment* ret)
648       ;; Loop through the infodb ...
649       (sb-c::do-info (env :class class :type type :name info-name
650                           :value value)
651         ;; ... looking for function or macro definitions
652         (when (and (eql class :function)
653                    (or (eql type :macro-function)
654                        (eql type :definition)))
655           ;; Get a simple-fun for the definition, and an xref array
656           ;; from the table if available.
657           (let* ((simple-fun (get-simple-fun value))
658                  (xrefs (when simple-fun
659                           (sb-kernel:%simple-fun-xrefs simple-fun)))
660                  (array (when xrefs
661                           (aref xrefs kind-index))))
662             ;; Loop through the name/path xref entries in the table
663             (loop for i from 0 below (length array) by 2
664                   for xref-name = (aref array i)
665                   for xref-path = (aref array (1+ i))
666                   do (when (equal xref-name wanted-name)
667                        (let ((source-location
668                               (find-function-definition-source simple-fun)))
669                          ;; Use the more accurate source path from
670                          ;; the xref entry.
671                          (setf (definition-source-form-path source-location)
672                                xref-path)
673                          (push (cons info-name source-location)
674                                ret))))))))))
675
676 (defun who-calls (function-name)
677   "Use the xref facility to search for source locations where the
678 global function named FUNCTION-NAME is called. Returns a list of
679 function name, definition-source pairs."
680   (collect-xref #.(position :calls sb-c::*xref-kinds*) function-name))
681
682 (defun who-binds (symbol)
683   "Use the xref facility to search for source locations where the
684 special variable SYMBOL is rebound. Returns a list of function name,
685 definition-source pairs."
686   (collect-xref #.(position :binds sb-c::*xref-kinds*) symbol))
687
688 (defun who-references (symbol)
689   "Use the xref facility to search for source locations where the
690 special variable or constant SYMBOL is read. Returns a list of function
691 name, definition-source pairs."
692   (collect-xref #.(position :references sb-c::*xref-kinds*) symbol))
693
694 (defun who-sets (symbol)
695   "Use the xref facility to search for source locations where the
696 special variable SYMBOL is written to. Returns a list of function name,
697 definition-source pairs."
698   (collect-xref #.(position :sets sb-c::*xref-kinds*) symbol))
699
700 (defun who-macroexpands (macro-name)
701   "Use the xref facility to search for source locations where the
702 macro MACRO-NAME is expanded. Returns a list of function name,
703 definition-source pairs."
704   (collect-xref #.(position :macroexpands sb-c::*xref-kinds*) macro-name))
705
706 (defun who-specializes-directly (class-designator)
707   "Search for source locations of methods directly specializing on
708 CLASS-DESIGNATOR. Returns an alist of method name, definition-source
709 pairs.
710
711 A method matches the criterion either if it specializes on the same
712 class as CLASS-DESIGNATOR designates (this includes CLASS-EQ
713 specializers), or if it eql-specializes on an instance of the
714 designated class.
715
716 Experimental.
717 "
718   (let ((class (canonicalize-class-designator class-designator)))
719     (unless class
720       (return-from who-specializes-directly nil))
721     (let ((result (collect-specializing-methods
722                    #'(lambda (specl)
723                        ;; Does SPECL specialize on CLASS directly?
724                        (typecase specl
725                          (sb-pcl::class-eq-specializer
726                           (eq (sb-pcl::specializer-object specl) class))
727                          (sb-pcl::eql-specializer
728                           (let ((obj (sb-mop:eql-specializer-object specl)))
729                             (eq (class-of obj) class)))
730                          ((not sb-pcl::standard-specializer)
731                           nil)
732                          (t
733                           (eq specl class)))))))
734       (map-into result #'(lambda (m)
735                            (cons `(method ,(method-generic-function-name m))
736                                  (find-definition-source m)))
737                 result))))
738
739 (defun who-specializes-generally (class-designator)
740   "Search for source locations of methods specializing on
741 CLASS-DESIGNATOR, or a subclass of it. Returns an alist of method
742 name, definition-source pairs.
743
744 A method matches the criterion either if it specializes on the
745 designated class itself or a subclass of it (this includes CLASS-EQ
746 specializers), or if it eql-specializes on an instance of the
747 designated class or a subclass of it.
748
749 Experimental.
750 "
751   (let ((class (canonicalize-class-designator class-designator)))
752     (unless class
753       (return-from who-specializes-generally nil))
754     (let ((result (collect-specializing-methods
755                    #'(lambda (specl)
756                        ;; Does SPECL specialize on CLASS or a subclass
757                        ;; of it?
758                        (typecase specl
759                          (sb-pcl::class-eq-specializer
760                           (subtypep (sb-pcl::specializer-object specl) class))
761                          (sb-pcl::eql-specializer
762                           (typep (sb-mop:eql-specializer-object specl) class))
763                          ((not sb-pcl::standard-specializer)
764                           nil)
765                          (t
766                           (subtypep specl class)))))))
767       (map-into result #'(lambda (m)
768                            (cons `(method ,(method-generic-function-name m))
769                                  (find-definition-source m)))
770                 result))))
771
772 (defun canonicalize-class-designator (class-designator)
773   (typecase class-designator
774     (symbol (find-class class-designator nil))
775     (class  class-designator)
776     (t nil)))
777
778 (defun method-generic-function-name (method)
779   (sb-mop:generic-function-name (sb-mop:method-generic-function method)))
780
781 (defun collect-specializing-methods (predicate)
782   (let ((result '()))
783     (sb-pcl::map-specializers
784      #'(lambda (specl)
785          (when (funcall predicate specl)
786            (let ((methods (sb-mop:specializer-direct-methods specl)))
787              (setf result (append methods result))))))
788     (delete-duplicates result)))
789
790
791 ;;;; ALLOCATION INTROSPECTION
792
793 (defun allocation-information (object)
794   #+sb-doc
795   "Returns information about the allocation of OBJECT. Primary return value
796 indicates the general type of allocation: :IMMEDIATE, :HEAP, :STACK,
797 or :FOREIGN.
798
799 Possible secondary return value provides additional information about the
800 allocation.
801
802 For :HEAP objects the secondary value is a plist:
803
804   :SPACE
805     Inficates the heap segment the object is allocated in.
806
807   :GENERATION
808     Is the current generation of the object: 0 for nursery, 6 for pseudo-static
809     generation loaded from core. (GENCGC and :SPACE :DYNAMIC only.)
810
811   :LARGE
812     Indicates a \"large\" object subject to non-copying
813     promotion. (GENCGC and :SPACE :DYNAMIC only.)
814
815   :BOXED
816     Indicates that the object is allocated in a boxed region. Unboxed
817     allocation is used for eg. specialized arrays after they have survived one
818     collection. (GENCGC and :SPACE :DYNAMIC only.)
819
820   :PINNED
821     Indicates that the page(s) on which the object resides are kept live due
822     to conservative references. Note that object may reside on a pinned page
823     even if :PINNED in NIL if the GC has not had the need to mark the the page
824     as pinned. (GENCGC and :SPACE :DYNAMIC only.)
825
826   :WRITE-PROTECTED
827     Indicates that the page on which the object starts is write-protected,
828     which indicates for :BOXED objects that it hasn't been written to since
829     the last GC of its generation. (GENCGC and :SPACE :DYNAMIC only.)
830
831   :PAGE
832     The index of the page the object resides on. (GENGC and :SPACE :DYNAMIC
833     only.)
834
835 For :STACK objects secondary value is the thread on whose stack the object is
836 allocated.
837
838 Expected use-cases include introspection to gain insight into allocation and
839 GC behaviour and restricting memoization to heap-allocated arguments.
840
841 Experimental: interface subject to change."
842   ;; FIXME: Would be nice to provide the size of the object as well, though
843   ;; maybe that should be a separate function, and something like MAP-PARTS
844   ;; for mapping over parts of arbitrary objects so users can get "deep sizes"
845   ;; as well if they want to.
846   ;;
847   ;; FIXME: For the memoization use-case possibly we should also provide a
848   ;; simpler HEAP-ALLOCATED-P, since that doesn't require disabling the GC
849   ;; scanning threads for negative answers? Similarly, STACK-ALLOCATED-P for
850   ;; checking if an object has been stack-allocated by a given thread for
851   ;; testing purposes might not come amiss.
852   (if (typep object '(or fixnum character))
853       (values :immediate nil)
854       (let ((plist
855              (sb-sys:without-gcing
856                ;; Disable GC so the object cannot move to another page while
857                ;; we have the address.
858                (let* ((addr (sb-kernel:get-lisp-obj-address object))
859                       (space
860                        (cond ((< sb-vm:read-only-space-start addr
861                                  (ash sb-vm:*read-only-space-free-pointer*
862                                       sb-vm:n-fixnum-tag-bits))
863                               :read-only)
864                              ((< sb-vm:static-space-start addr
865                                  (ash sb-vm:*static-space-free-pointer*
866                                       sb-vm:n-fixnum-tag-bits))
867                               :static)
868                              ((< (sb-kernel:current-dynamic-space-start) addr
869                                  (sb-sys:sap-int (sb-kernel:dynamic-space-free-pointer)))
870                               :dynamic))))
871                  (when space
872                    #+gencgc
873                    (if (eq :dynamic space)
874                        (let ((index (sb-vm::find-page-index addr)))
875                          (symbol-macrolet ((page (sb-alien:deref sb-vm::page-table index)))
876                            (let ((flags (sb-alien:slot page 'sb-vm::flags)))
877                              (list :space space
878                                    :generation (sb-alien:slot page 'sb-vm::gen)
879                                    :write-protected (logbitp 0 flags)
880                                    :boxed (logbitp 2 flags)
881                                    :pinned (logbitp 5 flags)
882                                    :large (logbitp 6 flags)
883                                    :page index))))
884                        (list :space space))
885                    #-gencgc
886                    (list :space space))))))
887         (cond (plist
888                (values :heap plist))
889               (t
890                (let ((sap (sb-sys:int-sap (sb-kernel:get-lisp-obj-address object))))
891                  ;; FIXME: Check other stacks as well.
892                  #+sb-thread
893                  (dolist (thread (sb-thread:list-all-threads))
894                    (let ((c-start (sb-di::descriptor-sap
895                                    (sb-thread::%symbol-value-in-thread
896                                     'sb-vm:*control-stack-start*
897                                     thread)))
898                          (c-end (sb-di::descriptor-sap
899                                  (sb-thread::%symbol-value-in-thread
900                                   'sb-vm:*control-stack-end*
901                                   thread))))
902                      (when (and c-start c-end)
903                        (when (and (sb-sys:sap<= c-start sap)
904                                   (sb-sys:sap< sap c-end))
905                          (return-from allocation-information
906                            (values :stack thread))))))
907                  #-sb-thread
908                  (when (sb-vm:control-stack-pointer-valid-p sap nil)
909                    (return-from allocation-information
910                      (values :stack sb-thread::*current-thread*))))
911                :foreign)))))
912
913 (defun map-root (function object &key simple (ext t))
914   "Call FUNCTION with all non-immediate objects pointed to by OBJECT.
915 Returns OBJECT.
916
917 If SIMPLE is true (default is NIL), elides those pointers that are not
918 notionally part of certain built-in objects, but backpointers to a
919 conceptual parent: eg. elides the pointer from a SYMBOL to the
920 corresponding PACKAGE.
921
922 If EXT is true (default is T), includes some pointers that are not
923 actually contained in the object, but found in certain well-known
924 indirect containers: FDEFINITIONs, EQL specializers, classes, and
925 thread-local symbol values in other threads fall into this category.
926
927 NOTE: calling MAP-ROOT with a THREAD does not currently map over
928 conservative roots from the thread registers and interrupt contexts.
929
930 Experimental: interface subject to change."
931   (let ((fun (coerce function 'function))
932         (seen (sb-int:alloc-xset)))
933     (flet ((call (part)
934              (when (and (member (sb-kernel:lowtag-of part)
935                                 `(,sb-vm:instance-pointer-lowtag
936                                   ,sb-vm:list-pointer-lowtag
937                                   ,sb-vm:fun-pointer-lowtag
938                                   ,sb-vm:other-pointer-lowtag))
939                         (not (sb-int:xset-member-p part seen)))
940                (sb-int:add-to-xset part seen)
941                (funcall fun part))))
942       (when ext
943         (let ((table sb-pcl::*eql-specializer-table*))
944           (call (sb-int:with-locked-system-table (table)
945                   (gethash object table)))))
946       (etypecase object
947         ((or bignum float sb-sys:system-area-pointer fixnum))
948         (sb-ext:weak-pointer
949          (call (sb-ext:weak-pointer-value object)))
950         (cons
951          (call (car object))
952          (call (cdr object))
953          (when (and ext (ignore-errors (fboundp object)))
954            (call (fdefinition object))))
955         (ratio
956          (call (numerator object))
957          (call (denominator object)))
958         (complex
959          (call (realpart object))
960          (call (realpart object)))
961         (sb-vm::instance
962          (let* ((len (sb-kernel:%instance-length object))
963                 (nuntagged (if (typep object 'structure-object)
964                                (sb-kernel:layout-n-untagged-slots
965                                 (sb-kernel:%instance-layout object))
966                                0)))
967            (dotimes (i (- len nuntagged))
968              (call (sb-kernel:%instance-ref object i))))
969          #+sb-thread
970          (when (typep object 'sb-thread:thread)
971            (cond ((eq object sb-thread:*current-thread*)
972                   (dolist (value (sb-thread::%thread-local-references))
973                     (call value))
974                   (sb-vm::map-stack-references #'call))
975                  (t
976                   ;; KLUDGE: INTERRUPT-THREAD is Not Nice (tm), but
977                   ;; the alternative would be stopping the world...
978                   #+sb-thread
979                   (let ((sem (sb-thread:make-semaphore))
980                         (refs nil))
981                     (handler-case
982                         (progn
983                           (sb-thread:interrupt-thread
984                            object
985                            (lambda ()
986                              (setf refs (sb-thread::%thread-local-references))
987                              (sb-vm::map-stack-references (lambda (x) (push x refs)))
988                              (sb-thread:signal-semaphore sem)))
989                           (sb-thread:wait-on-semaphore sem))
990                       (sb-thread:interrupt-thread-error ()))
991                     (mapc #'call refs))))))
992         (array
993          (if (simple-vector-p object)
994              (dotimes (i (length object))
995                (call (aref object i)))
996              (when (sb-kernel:array-header-p object)
997                (call (sb-kernel::%array-data-vector object))
998                (call (sb-kernel::%array-displaced-p object))
999                (unless simple
1000                  (call (sb-kernel::%array-displaced-from object))))))
1001         (sb-kernel:code-component
1002          (call (sb-kernel:%code-entry-points object))
1003          (call (sb-kernel:%code-debug-info object))
1004          (loop for i from sb-vm:code-constants-offset
1005                below (sb-kernel:get-header-data object)
1006                do (call (sb-kernel:code-header-ref object i))))
1007         (sb-kernel:fdefn
1008          (call (sb-kernel:fdefn-name object))
1009          (call (sb-kernel:fdefn-fun object)))
1010         (sb-kernel:simple-fun
1011          (unless simple
1012            (call (sb-kernel:%simple-fun-next object)))
1013          (call (sb-kernel:fun-code-header object))
1014          (call (sb-kernel:%simple-fun-name object))
1015          (call (sb-kernel:%simple-fun-arglist object))
1016          (call (sb-kernel:%simple-fun-type object))
1017          (call (sb-kernel:%simple-fun-info object)))
1018         (sb-kernel:closure
1019          (call (sb-kernel:%closure-fun object))
1020          (sb-kernel:do-closure-values (x object)
1021            (call x)))
1022         (sb-kernel:funcallable-instance
1023          (call (sb-kernel:%funcallable-instance-function object))
1024          (loop for i from 1 below (- (1+ (sb-kernel:get-closure-length object))
1025                                      sb-vm::funcallable-instance-info-offset)
1026                do (call (sb-kernel:%funcallable-instance-info object i))))
1027         (symbol
1028          (when ext
1029            (dolist (thread (sb-thread:list-all-threads))
1030              (call (sb-thread:symbol-value-in-thread object thread nil))))
1031          (handler-case
1032              ;; We don't have GLOBAL-BOUNDP, and there's no ERRORP arg.
1033              (call (sb-ext:symbol-global-value object))
1034            (unbound-variable ()))
1035          (when (and ext (ignore-errors (fboundp object)))
1036            (call (fdefinition object))
1037            (call (macro-function object))
1038            (let ((class (find-class object nil)))
1039              (when class (call class))))
1040          (call (symbol-plist object))
1041          (call (symbol-name object))
1042          (unless simple
1043            (call (symbol-package object))))
1044         (sb-kernel::random-class
1045          (case (sb-kernel:widetag-of object)
1046            (#.sb-vm::value-cell-header-widetag
1047             (call (sb-kernel::value-cell-ref object)))
1048            (t
1049             (warn "~&MAP-ROOT: Unknown widetag ~S: ~S~%"
1050                   (sb-kernel:widetag-of object) object)))))))
1051   object)