Avoid freeing literal memory.
[sbcl.git] / contrib / sb-introspect / introspect.lisp
blobf3aea03106deb87bc17005ae9d5ed9d807e7bf0c
1 ;;; introspection library
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.
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.
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.
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
29 (defpackage :sb-introspect
30 (:use "CL" "SB-KERNEL" "SB-INT")
31 (:import-from "SB-VM" "PRIMITIVE-OBJECT-SIZE")
32 (:shadow "VALID-FUNCTION-NAME-P")
33 (:export "ALLOCATION-INFORMATION"
34 "FUNCTION-ARGLIST"
35 "FUNCTION-LAMBDA-LIST"
36 "FUNCTION-TYPE"
37 "METHOD-COMBINATION-LAMBDA-LIST"
38 "DEFTYPE-LAMBDA-LIST"
39 "VALID-FUNCTION-NAME-P"
40 "FIND-DEFINITION-SOURCE"
41 "FIND-DEFINITION-SOURCES-BY-NAME"
42 "DEFINITION-SOURCE"
43 "DEFINITION-SOURCE-PATHNAME"
44 "DEFINITION-SOURCE-FORM-PATH"
45 "DEFINITION-SOURCE-FORM-NUMBER"
46 "DEFINITION-SOURCE-CHARACTER-OFFSET"
47 "DEFINITION-SOURCE-FILE-WRITE-DATE"
48 "DEFINITION-SOURCE-PLIST"
49 "FIND-FUNCTION-CALLEES"
50 "FIND-FUNCTION-CALLERS"
51 "MAP-ROOT"
52 "WHO-BINDS"
53 "WHO-CALLS"
54 "WHO-REFERENCES"
55 "WHO-SETS"
56 "WHO-MACROEXPANDS"
57 "WHO-SPECIALIZES-DIRECTLY"
58 "WHO-SPECIALIZES-GENERALLY"))
60 (in-package :sb-introspect)
61 (eval-when (:compile-toplevel :load-toplevel :execute)
62 (setf (system-package-p *package*) t))
64 ;;;; Internal interface for SBCL debug info
66 ;;; Here are some tutorial-style type definitions to help understand
67 ;;; the internal SBCL debugging data structures we're using. The
68 ;;; commentary is based on CMUCL's debug internals manual.
69 ;;;
70 (deftype debug-info ()
71 "Structure containing all the debug information related to a function.
72 Function objects reference debug-infos which in turn reference
73 debug-sources and so on."
74 'sb-c::compiled-debug-info)
76 (deftype debug-source ()
77 "Debug sources describe where to find source code.
78 For example, the debug source for a function compiled from a file will
79 include the pathname of the file and the position of the definition."
80 'sb-c::debug-source)
82 (declaim (ftype (sfunction (function) debug-info) function-debug-info))
83 (defun function-debug-info (function)
84 (let* ((function-object (%fun-fun function))
85 (function-header (fun-code-header function-object)))
86 (%code-debug-info function-header)))
88 (declaim (ftype (sfunction (function) debug-source) function-debug-source))
89 (defun function-debug-source (function)
90 (debug-info-source (function-debug-info function)))
92 (declaim (ftype (sfunction (debug-info) debug-source) debug-info-source))
93 (defun debug-info-source (debug-info)
94 (sb-c::debug-info-source debug-info))
96 (defun valid-function-name-p (name)
97 "True if NAME denotes a valid function name, ie. one that can be passed to
98 FBOUNDP."
99 (and (sb-int:valid-function-name-p name) t))
101 ;;;; Utilities for code
103 (declaim (inline map-code-constants))
104 (defun map-code-constants (code fn)
105 "Call FN for each constant in CODE's constant pool."
106 (check-type code code-component)
107 (loop for i from sb-vm:code-constants-offset below (code-header-words code)
108 do (funcall fn (code-header-ref code i))))
110 (declaim (inline map-allocated-code-components))
111 (defun map-allocated-code-components (spaces fn)
112 "Call FN for each allocated code component in one of SPACES. FN
113 receives the object and its size as arguments. SPACES should be a
114 list of the symbols :dynamic, :static, :read-only, or :immobile on
115 #+immobile-space"
116 (apply #'sb-vm:map-allocated-objects
117 (lambda (obj header size)
118 (when (= sb-vm:code-header-widetag header)
119 (funcall fn obj size)))
120 spaces))
122 (declaim (inline map-caller-code-components))
123 (defun map-caller-code-components (function spaces fn)
124 "Call FN for each code component with a fdefn for FUNCTION in its
125 constant pool."
126 (let ((function (coerce function 'function)))
127 (map-allocated-code-components
128 spaces
129 (lambda (obj size)
130 (declare (ignore size))
131 (map-code-constants
133 (lambda (constant)
134 (when (and (fdefn-p constant)
135 (eq (fdefn-fun constant) function))
136 (funcall fn obj))))))))
138 ;;;; Finding definitions
140 (defstruct definition-source
141 ;; Pathname of the source file that the definition was compiled from.
142 ;; This is null if the definition was not compiled from a file.
143 (pathname nil :type (or null pathname))
144 ;; Source-path of the definition within the file.
145 ;; This may be incomplete depending on the debug level at which the
146 ;; source was compiled.
147 (form-path '() :type list)
148 ;; Depth first number of the form.
149 ;; FORM-PATH above usually contains just the top-level form number,
150 ;; ideally the proper form path could be dervied from the
151 ;; form-number and the tlf-number, but it's a bit complicated and
152 ;; Slime already knows how to deal with form numbers, so delegate
153 ;; that job to Slime.
154 (form-number nil :type (or null unsigned-byte))
155 ;; Character offset of the top-level-form containing the definition.
156 ;; This corresponds to the first element of form-path.
157 (character-offset nil :type (or null unsigned-byte))
158 ;; File-write-date of the source file when compiled.
159 ;; Null if not compiled from a file.
160 (file-write-date nil :type (or null unsigned-byte))
161 ;; plist from WITH-COMPILATION-UNIT
162 (plist nil)
163 ;; Any extra metadata that the caller might be interested in. For
164 ;; example the specializers of the method whose definition-source this
165 ;; is.
166 (description nil :type list))
168 (defun vops-translating-fun (name)
169 (let ((fun-info (info :function :info name)))
170 (when fun-info
171 (sb-c::fun-info-templates fun-info))))
173 (defun find-vop-source (name)
174 (let* ((vop (gethash name sb-c::*backend-parsed-vops*))
175 (translating (vops-translating-fun name))
176 (vops (if vop
177 (cons vop (remove vop translating))
178 translating)))
179 (loop for vop in vops
180 for vop-parse = (if (typep vop 'sb-c::vop-parse)
182 (gethash (sb-c::vop-info-name vop)
183 sb-c::*backend-parsed-vops*))
184 for name = (and vop-parse
185 (sb-c::vop-parse-name vop-parse))
186 for loc = (and vop-parse
187 (sb-c::vop-parse-source-location vop-parse))
188 when loc
189 collect (let ((source (translate-source-location loc)))
190 (setf (definition-source-description source)
191 (if (sb-c::vop-parse-note vop-parse)
192 (list name (sb-c::vop-parse-note vop-parse))
193 (list name)))
194 source))))
196 (defun find-definition-sources-by-name (name type)
197 "Returns a list of DEFINITION-SOURCEs for the objects of type TYPE
198 defined with name NAME. NAME may be a symbol or a extended function
199 name. Type can currently be one of the following:
201 (Public)
202 :CLASS
203 :COMPILER-MACRO
204 :CONDITION
205 :CONSTANT
206 :FUNCTION
207 :GENERIC-FUNCTION
208 :MACRO
209 :METHOD
210 :METHOD-COMBINATION
211 :PACKAGE
212 :SETF-EXPANDER
213 :STRUCTURE
214 :SYMBOL-MACRO
215 :TYPE
216 :ALIEN-TYPE
217 :VARIABLE
218 :DECLARATION
220 (Internal)
221 :OPTIMIZER
222 :SOURCE-TRANSFORM
223 :TRANSFORM
224 :VOP
225 :IR1-CONVERT
227 If an unsupported TYPE is requested, the function will return NIL.
229 (flet ((get-class (name)
230 (and (symbolp name)
231 (find-class name nil)))
232 (real-fdefinition (name)
233 ;; for getting the real function object, even if the
234 ;; function is being profiled
235 (let ((profile-info (gethash name sb-profile::*profiled-fun-name->info*)))
236 (if profile-info
237 (sb-profile::profile-info-encapsulated-fun profile-info)
238 (fdefinition name)))))
239 (ensure-list
240 (case type
241 ((:variable)
242 (when (and (symbolp name)
243 (member (info :variable :kind name)
244 '(:global :special :alien)))
245 (translate-source-location (info :source-location type name))))
246 ((:constant)
247 (when (and (symbolp name)
248 (eq (info :variable :kind name) :constant))
249 (translate-source-location (info :source-location type name))))
250 ((:symbol-macro)
251 (when (and (symbolp name)
252 (eq (info :variable :kind name) :macro))
253 (translate-source-location (info :source-location type name))))
254 ((:macro)
255 (when (and (symbolp name)
256 (macro-function name))
257 (find-definition-source (macro-function name))))
258 ((:compiler-macro)
259 (when (compiler-macro-function name)
260 (find-definition-source (compiler-macro-function name))))
261 (:ir1-convert
262 (let ((converter (info :function :ir1-convert name)))
263 (and converter
264 (find-definition-source converter))))
265 ((:function :generic-function)
266 (when (and (fboundp name)
267 (or (consp name)
268 (and
269 (not (macro-function name))
270 (not (special-operator-p name)))))
271 (let ((fun (real-fdefinition name)))
272 (when (eq (not (typep fun 'generic-function))
273 (not (eq type :generic-function)))
274 (find-definition-source fun)))))
275 ((:type)
276 ;; Source locations for types are saved separately when the expander
277 ;; is a closure without a good source-location.
278 (let ((loc (info :type :source-location name)))
279 (if loc
280 (translate-source-location loc)
281 (let ((expander-fun (info :type :expander name)))
282 (when (functionp expander-fun)
283 (find-definition-source expander-fun))))))
284 ((:method)
285 (when (fboundp name)
286 (let ((fun (real-fdefinition name)))
287 (when (typep fun 'generic-function)
288 (loop for method in (sb-mop::generic-function-methods
289 fun)
290 for source = (find-definition-source method)
291 when source collect source)))))
292 ((:setf-expander)
293 (when (and (consp name)
294 (eq (car name) 'setf))
295 (setf name (cadr name)))
296 (let ((expander (info :setf :expander name)))
297 (cond ((typep expander '(cons symbol))
298 (translate-source-location (cddr expander)))
299 (expander
300 (find-definition-source
301 (if (listp expander) (cdr expander) expander))))))
302 ((:structure)
303 (let ((class (get-class name)))
304 (if class
305 (when (typep class 'sb-pcl::structure-class)
306 (find-definition-source class))
307 (when (info :typed-structure :info name)
308 (translate-source-location
309 (info :source-location :typed-structure name))))))
310 ((:condition :class)
311 (let ((class (get-class name)))
312 (when (and class
313 (not (typep class 'sb-pcl::structure-class)))
314 (when (eq (not (typep class 'sb-pcl::condition-class))
315 (not (eq type :condition)))
316 (find-definition-source class)))))
317 ((:method-combination)
318 (let ((info (gethash name sb-pcl::**method-combinations**)))
319 (when info
320 (translate-source-location
321 (sb-pcl::method-combination-info-source-location info)))))
322 ((:package)
323 (when (symbolp name)
324 (let ((package (find-package name)))
325 (when package
326 (find-definition-source package)))))
327 ;; TRANSFORM and OPTIMIZER handling from swank-sbcl
328 ((:transform)
329 (let ((fun-info (info :function :info name)))
330 (when fun-info
331 (loop for xform in (sb-c::fun-info-transforms fun-info)
332 for source = (find-definition-source
333 (sb-c::transform-function xform))
334 for typespec = (type-specifier
335 (sb-c::transform-type xform))
336 for note = (sb-c::transform-note xform)
337 do (setf (definition-source-description source)
338 (if (consp typespec)
339 (list (second typespec) note)
340 (list note)))
341 collect source))))
342 ((:optimizer)
343 (let ((fun-info (and (symbolp name)
344 (info :function :info name))))
345 (when fun-info
346 (let ((otypes '((sb-c:fun-info-derive-type . sb-c:derive-type)
347 (sb-c:fun-info-ltn-annotate . sb-c:ltn-annotate)
348 (sb-c:fun-info-optimizer . sb-c:optimizer)
349 (sb-c:fun-info-ir2-convert . sb-c:ir2-convert)
350 (sb-c::fun-info-ir2-hook . sb-c::ir2-hook)
351 (sb-c::fun-info-stack-allocate-result
352 . sb-c::stack-allocate-result)
353 (sb-c::fun-info-constraint-propagate
354 . sb-c::constraint-propagate)
355 (sb-c::fun-info-constraint-propagate-if
356 . sb-c::constraint-propagate-if)
357 (sb-c::fun-info-call-type-deriver
358 . sb-c::call-type-deriver))))
359 (loop for (reader . name) in otypes
360 for fn = (funcall reader fun-info)
361 when fn collect
362 (let ((source (find-definition-source fn)))
363 (setf (definition-source-description source)
364 (list name))
365 source))))))
366 (:vop
367 (find-vop-source name))
368 (:alien-type
369 (let ((loc (info :source-location type name)))
370 (and loc
371 (translate-source-location loc))))
372 ((:source-transform)
373 (let* ((transform-fun
374 (or (info :function :source-transform name)
375 (and (typep name '(cons (eql setf) (cons symbol null)))
376 (info :function :source-transform
377 (second name)))))
378 ;; A cons for the :source-transform is essentially the same
379 ;; info that was formerly in :structure-accessor.
380 (accessor (and (consp transform-fun) (cdr transform-fun))))
381 ;; Structure accessors have source transforms, but the
382 ;; returned locations will neither show the actual place
383 ;; where it's defined, nor is really interesting.
384 (when (and transform-fun
385 (not accessor))
386 (find-definition-source transform-fun))))
387 (:declaration
388 (let ((locations (info :source-location :declaration name)))
389 (loop for (kind loc) on locations by #'cddr
390 when loc
391 collect (let ((loc (translate-source-location loc)))
392 (setf (definition-source-description loc)
393 ;; Copy list to ensure that user code
394 ;; cannot mutate the original.
395 (copy-list (ensure-list kind)))
396 loc))))
398 nil)))))
400 (defun find-definition-source (object)
401 (typecase object
402 ((or sb-pcl::condition-class sb-pcl::structure-class)
403 (let ((classoid (sb-pcl::class-classoid object)))
404 (when classoid
405 (translate-source-location
406 (sb-kernel::classoid-source-location classoid)))))
407 (method-combination
408 (car
409 (find-definition-sources-by-name
410 (sb-pcl::method-combination-type-name object) :method-combination)))
411 (package
412 (translate-source-location (sb-impl::package-source-location object)))
413 ((or class sb-mop:slot-definition)
414 (translate-source-location (sb-pcl::definition-source object)))
415 ;; Use the PCL definition location information instead of the function
416 ;; debug-info for methods and generic functions. Sometimes the
417 ;; debug-info would point into PCL internals instead of the proper
418 ;; location.
419 (generic-function
420 (let ((source (translate-source-location
421 (sb-pcl::definition-source object))))
422 (when source
423 (setf (definition-source-description source)
424 (list (sb-mop:generic-function-lambda-list object))))
425 source))
426 (method
427 (let ((source (translate-source-location
428 (sb-pcl::definition-source object))))
429 (when source
430 (setf (definition-source-description source)
431 (append (method-qualifiers object)
432 (if (sb-mop:method-generic-function object)
433 (sb-pcl::unparse-specializers
434 (sb-mop:method-generic-function object)
435 (sb-mop:method-specializers object))
436 (sb-mop:method-specializers object)))))
437 source))
438 (interpreted-function
439 #+sb-eval
440 (let ((source (translate-source-location
441 (sb-eval:interpreted-function-source-location object))))
442 source)
443 #+sb-fasteval
444 (translate-source-location (sb-interpreter:fun-source-location object)))
445 (function
446 (find-function-definition-source object))
447 ((or condition standard-object structure-object)
448 (find-definition-source (class-of object)))
450 (error "Don't know how to retrieve source location for a ~S"
451 (type-of object)))))
453 (defun find-function-definition-source (function)
454 (let* ((debug-source (debug-info-source (function-debug-info function)))
455 (debug-fun (sb-di::fun-debug-fun function))
456 (tlf (sb-c::compiled-debug-fun-tlf-number
457 (sb-di::compiled-debug-fun-compiler-debug-fun debug-fun))))
458 (make-definition-source
459 :pathname
460 (when (stringp (sb-c::debug-source-namestring debug-source))
461 (parse-namestring (sb-c::debug-source-namestring debug-source)))
462 :character-offset
463 (if tlf
464 (elt (sb-c::debug-source-start-positions debug-source) tlf))
465 :form-path (if tlf (list tlf))
466 :form-number (handler-case (sb-di::code-location-form-number
467 (sb-di::debug-fun-start-location debug-fun))
468 (sb-di::unknown-code-location (cond)
469 (declare (ignore cond))
470 (sb-c::compiled-debug-fun-blocks
471 (sb-di::compiled-debug-fun-compiler-debug-fun debug-fun))))
472 :file-write-date (sb-c::debug-source-created debug-source)
473 :plist (sb-c::debug-source-plist debug-source))))
475 (defun translate-source-location (location)
476 (if location
477 (make-definition-source
478 :pathname (let ((n (sb-c:definition-source-location-namestring location)))
479 (when n
480 (parse-namestring n)))
481 :form-path
482 (let ((number (sb-c:definition-source-location-toplevel-form-number
483 location)))
484 (when number
485 (list number)))
486 :form-number (sb-c:definition-source-location-form-number
487 location)
488 :plist (sb-c:definition-source-location-plist location))
489 (make-definition-source)))
491 (define-deprecated-function :late "1.0.24.5" function-arglist function-lambda-list
492 (function)
493 (function-lambda-list function))
495 (defun function-lambda-list (function)
496 "Return the lambda list for the extended function designator FUNCTION.
497 Works for special-operators, macros, simple functions, interpreted functions,
498 and generic functions. Signals an error if FUNCTION is not a valid extended
499 function designator.
501 If the function does not have a lambda list (compiled with debug 0),
502 then two values are returned: (values nil t)"
503 (cond ((and (symbolp function) (special-operator-p function))
504 (function-lambda-list (info :function :ir1-convert function)))
505 ((valid-function-name-p function)
506 (function-lambda-list (or (and (symbolp function)
507 (macro-function function))
508 (fdefinition function))))
509 ((typep function 'generic-function)
510 (sb-pcl::generic-function-pretty-arglist function))
512 (let ((raw-result (%fun-lambda-list function)))
513 (if (eq raw-result :unknown)
514 (values nil t)
515 (values raw-result nil))))))
517 (defun deftype-lambda-list (typespec-operator)
518 "Returns the lambda list of TYPESPEC-OPERATOR as first return
519 value, and a flag whether the arglist could be found as second
520 value."
521 (check-type typespec-operator symbol)
522 ;; Don't return a lambda-list for combinators AND,OR,NOT.
523 (let* ((f (and (info :type :kind typespec-operator)
524 (info :type :expander typespec-operator)))
525 (f (if (listp f) (car f) f)))
526 (if (functionp f)
527 (values (%fun-lambda-list f) t)
528 (values nil nil))))
530 (defun method-combination-lambda-list (method-combination)
531 "Return the lambda-list of METHOD-COMBINATION designator.
532 METHOD-COMBINATION can be a method combination object,
533 or a method combination name."
534 (let* ((name (etypecase method-combination
535 (symbol method-combination)
536 (method-combination
537 (sb-pcl::method-combination-type-name method-combination))))
538 (info (or (gethash name sb-pcl::**method-combinations**)
539 (error "~S: no such method combination." name))))
540 (sb-pcl::method-combination-info-lambda-list info)))
542 (defun function-type (function-designator)
543 "Returns the ftype of FUNCTION-DESIGNATOR, or NIL."
544 (etypecase function-designator
545 ((or symbol cons)
546 ;; XXX: why require FBOUNDP? Would it be wrong to always report the proclaimed type?
547 (when (and (legal-fun-name-p function-designator) ; guarding FBOUNDP against error
548 (fboundp function-designator)
549 (eq (info :function :kind function-designator) :function))
550 (type-specifier (global-ftype function-designator))))
551 (function
552 (let ((name (%fun-name function-designator)))
553 (if (and (legal-fun-name-p name)
554 (fboundp name)
555 ;; It seems inappropriate to report the global ftype if this
556 ;; function is not the current binding of the global name,
557 (eq (fdefinition name) function-designator))
558 ;; Give declared type in globaldb priority over derived type
559 ;; because it contains more accurate information e.g. for
560 ;; struct-accessors.
561 (function-type name)
562 (sb-impl::%fun-ftype function-designator))))))
564 ;;;; find callers/callees, liberated from Helmut Eller's code in SLIME
566 ;;; This interface is tremendously experimental.
568 ;;; For the moment I'm taking the view that FDEFN is an internal
569 ;;; object (one out of one CMUCL developer surveyed didn't know what
570 ;;; they were for), so these routines deal in FUNCTIONs
572 ;;; Find callers and callees by looking at the constant pool of
573 ;;; compiled code objects. We assume every fdefn object in the
574 ;;; constant pool corresponds to a call to that function. A better
575 ;;; strategy would be to use the disassembler to find actual
576 ;;; call-sites.
578 (defun find-function-callees (function)
579 "Return functions called by FUNCTION."
580 (if (typep function 'generic-function)
581 (loop for method in (sb-mop:generic-function-methods function)
582 for method-fun = (sb-mop:method-function method)
583 append (find-function-callees
584 (if (typep (%fun-name method-fun) '(cons (eql sb-pcl::call)))
585 (sb-kernel:%closure-index-ref method-fun 0)
586 method-fun)))
587 (let ((callees '()))
588 (map-code-constants
589 (fun-code-header (sb-kernel:%fun-fun function))
590 (lambda (obj)
591 (when (fdefn-p obj)
592 (let ((fun (fdefn-fun obj)))
593 (when fun
594 (push fun callees))))))
595 callees)))
597 (defun find-function-callers (function &optional (spaces '(:read-only :static
598 :dynamic
599 #+immobile-code :immobile)))
600 "Return functions which call FUNCTION, by searching SPACES for code objects"
601 (let ((referrers '()))
602 (map-caller-code-components
603 function
604 spaces
605 (lambda (code)
606 (dotimes (i (code-n-entries code))
607 (pushnew (%code-entry-point code i) referrers))))
608 referrers))
610 ;;; XREF facility
612 #-(and system-tlabs (not mark-region-gc))
613 (progn
614 (labels ((functoid-simple-fun (functoid)
615 ;; looks like this is supposed to ignore INTERPRETED-FUNCTION ?
616 (typecase functoid
617 (simple-fun functoid)
618 (closure
619 (let ((fun (%closure-fun functoid)))
620 (if (and (eq (%fun-name fun) 'sb-impl::encapsulation))
621 (functoid-simple-fun
622 (sb-impl::encapsulation-info-definition
623 (sb-impl::encapsulation-info functoid)))
624 fun))))))
625 (defun map-simple-funs (function)
626 (let ((function (%coerce-callable-to-fun function)))
627 (labels ((process (name value)
628 (awhen (functoid-simple-fun value)
629 (funcall function name it))))
630 (call-with-each-globaldb-name
631 (lambda (name)
632 ;; Methods are processed with their generic function
633 (unless (typep name '(cons (member sb-pcl::slow-method sb-pcl::fast-method)))
634 (let ((f (or (and (symbolp name) (macro-function name))
635 (and (legal-fun-name-p name) (fboundp name)))))
636 (typecase f
637 (generic-function
638 (loop for method in (sb-mop:generic-function-methods f)
639 for fun = (sb-pcl::safe-method-fast-function method)
640 when fun do (process (sb-kernel:%fun-name fun) fun)))
641 (function
642 (process name f)))))
643 #+sb-xref-for-internals
644 (let ((info (info :function :info name)))
645 (when info
646 (loop for transform in (sb-c::fun-info-transforms info)
647 for fun = (sb-c::transform-function transform)
648 ;; Defined using :defun-only and a later %deftransform.
649 unless (symbolp fun)
650 do (process transform fun))))))
651 #+sb-xref-for-internals
652 (sb-int:dohash ((name vop) sb-c::*backend-template-names*)
653 (declare (ignore name))
654 (let ((fun (sb-c::vop-info-generator-function vop)))
655 (when fun
656 (process vop fun))))))))
657 (defun collect-xref (wanted-kind wanted-name)
658 (let ((result '()))
659 (map-simple-funs
660 (lambda (name fun)
661 (binding* ((xrefs (%simple-fun-xrefs fun) :exit-if-null))
662 (sb-c:map-packed-xref-data
663 (lambda (xref-kind xref-name xref-form-number)
664 (when (and (eq xref-kind wanted-kind)
665 (equal xref-name wanted-name))
666 (let ((source-location (find-function-definition-source fun)))
667 ;; Use the more accurate source path from the xref
668 ;; entry.
669 (setf (definition-source-form-number source-location)
670 xref-form-number)
671 (let ((name (cond ((sb-c::transform-p name)
672 (let ((fun-name (%fun-name fun)))
673 (append (if (consp fun-name)
674 fun-name
675 (list fun-name))
676 (let* ((type (sb-c::transform-type name))
677 (type-spec (type-specifier type)))
678 (and (sb-kernel:fun-type-p type)
679 (list (second type-spec)))))))
680 ((sb-c::vop-info-p name)
681 (list 'sb-c:define-vop
682 (sb-c::vop-info-name name)))
684 name))))
685 (push (cons name source-location) result)))))
686 xrefs))))
687 result)))
689 #+(and system-tlabs (not mark-region-gc))
690 (progn
691 (sb-ext:defglobal *codeblob-cache* nil)
692 (flet ((gather-code (stamp) ; = the value of sb-vm::*code-alloc-count*
693 ;; Remove unreachable functions.
694 (sb-ext:gc :full t)
695 (let ((arena (sb-vm:new-arena (* 2 1024 1024)))
696 (result))
697 ;; Can allocate inside an arena while holding without-gcing in sb-vm:map-code-objects
698 ;; Anyway this approach is silly because Lisp should maintain at all times
699 ;; a binary-searchable tree of all code which would solve all problems
700 ;; related to finding a codeblob from a PC without relying on whatever
701 ;; a particular GC implementation exposes in terms of linearly searchable
702 ;; ranges of memory. immobile-space does maintain such a tree. Of course the tree
703 ;; should also _weakly_ reference all code, and should be usable for xref
704 ;; and other consumers beside the debugger. And it should come with a pony too.
705 (unwind-protect
706 (sb-vm:with-arena (arena)
707 ;; No filtering since we want this to pertain to all COLLECT-XREFS calls
708 (sb-vm:map-code-objects (lambda (code) (push code result))))
709 ;; arenas are not suitable for returning memoized data
710 (setq result (coerce result 'vector))
711 (sb-vm:destroy-arena arena))
712 (setf *codeblob-cache* (cons stamp (sb-ext:make-weak-pointer result)))
713 result)))
714 (defun collect-xref (wanted-kind wanted-name)
715 (let* ((current-stamp sb-vm::*code-alloc-count*)
716 (all-code
717 ;; this is not an attempt to be 100% correct in observing an up-to-date
718 ;; snapshot at a point in time. It's close enough though.
719 ;; I can't imagine that users are clamoring for a perfect solution to
720 ;; racing threads and XREFing jit-compiled code.
721 (or (let ((cache *codeblob-cache*))
722 (and (eql (car cache) current-stamp)
723 (sb-ext:weak-pointer-value (cdr cache))))
724 (loop ; expect exactly 1 iteration
725 (let ((vector (gather-code current-stamp))
726 (new-stamp sb-vm::*code-alloc-count*))
727 (if (eq new-stamp current-stamp) ; say it's done
728 (return vector)
729 (setq current-stamp new-stamp))))))
730 (funs))
731 (dovector (code all-code)
732 (dotimes (i (code-n-entries code))
733 (let ((fun (%code-entry-point code i)))
734 (binding* ((xrefs (%simple-fun-xrefs fun) :exit-if-null))
735 (sb-c:map-packed-xref-data
736 (lambda (xref-kind xref-name xref-form-number)
737 (when (and (eq xref-kind wanted-kind)
738 (equal xref-name wanted-name))
739 (push (cons fun xref-form-number) funs)))
740 xrefs)))))
741 (let (result)
742 (loop for (fun . xref-form-number) in funs
744 (let ((source-location (find-function-definition-source fun)))
745 ;; Use the more accurate source path from the xref
746 ;; entry.
747 (setf (definition-source-form-number source-location) xref-form-number)
748 (let* ((name (sb-c::%fun-name fun))
749 (name (cond ((typep name '(cons (eql sb-c:deftransform)))
750 (let* ((fun-name (second name))
751 (info (sb-int:info :function :info fun-name))
752 (transform (and info
753 (find fun (sb-c::fun-info-transforms info)
754 :key #'sb-c::transform-function))))
755 (if transform
756 (append name
757 (let* ((type (sb-c::transform-type transform))
758 (type-spec (type-specifier type)))
759 (and (sb-kernel:fun-type-p type)
760 (list (second type-spec)))))
761 name)))
763 name))))
764 (pushnew (cons name source-location) result :test #'equalp))))
765 result)))))
767 (defun who-calls (function-name)
768 "Use the xref facility to search for source locations where the
769 global function named FUNCTION-NAME is called. Returns a list of
770 function name, definition-source pairs."
771 (collect-xref :calls function-name))
773 (defun who-binds (symbol)
774 "Use the xref facility to search for source locations where the
775 special variable SYMBOL is rebound. Returns a list of function name,
776 definition-source pairs."
777 (collect-xref :binds symbol))
779 (defun who-references (symbol)
780 "Use the xref facility to search for source locations where the
781 special variable or constant SYMBOL is read. Returns a list of function
782 name, definition-source pairs."
783 (collect-xref :references symbol))
785 (defun who-sets (symbol)
786 "Use the xref facility to search for source locations where the
787 special variable SYMBOL is written to. Returns a list of function name,
788 definition-source pairs."
789 (collect-xref :sets symbol))
791 (defun who-macroexpands (macro-name)
792 "Use the xref facility to search for source locations where the
793 macro MACRO-NAME is expanded. Returns a list of function name,
794 definition-source pairs."
795 (collect-xref :macroexpands macro-name))
797 (defun who-specializes-directly (class-designator)
798 "Search for source locations of methods directly specializing on
799 CLASS-DESIGNATOR. Returns an alist of method name, definition-source
800 pairs.
802 A method matches the criterion either if it specializes on the same
803 class as CLASS-DESIGNATOR designates (this includes CLASS-EQ
804 specializers), or if it eql-specializes on an instance of the
805 designated class.
807 Experimental.
809 (let ((class (canonicalize-class-designator class-designator)))
810 (unless class
811 (return-from who-specializes-directly nil))
812 (let ((result (collect-specializing-methods
813 #'(lambda (specl)
814 ;; Does SPECL specialize on CLASS directly?
815 (typecase specl
816 (sb-pcl::class-eq-specializer
817 (eq (sb-pcl::specializer-object specl) class))
818 (sb-pcl::eql-specializer
819 (let ((obj (sb-mop:eql-specializer-object specl)))
820 (eq (class-of obj) class)))
821 ((not sb-pcl::standard-specializer)
822 nil)
824 (eq specl class)))))))
825 (map-into result #'(lambda (m)
826 (cons `(method ,(method-generic-function-name m))
827 (find-definition-source m)))
828 result))))
830 (defun who-specializes-generally (class-designator)
831 "Search for source locations of methods specializing on
832 CLASS-DESIGNATOR, or a subclass of it. Returns an alist of method
833 name, definition-source pairs.
835 A method matches the criterion either if it specializes on the
836 designated class itself or a subclass of it (this includes CLASS-EQ
837 specializers), or if it eql-specializes on an instance of the
838 designated class or a subclass of it.
840 Experimental.
842 (let ((class (canonicalize-class-designator class-designator)))
843 (unless class
844 (return-from who-specializes-generally nil))
845 (let ((result (collect-specializing-methods
846 #'(lambda (specl)
847 ;; Does SPECL specialize on CLASS or a subclass
848 ;; of it?
849 (typecase specl
850 (sb-pcl::class-eq-specializer
851 (subtypep (sb-pcl::specializer-object specl) class))
852 (sb-pcl::eql-specializer
853 (typep (sb-mop:eql-specializer-object specl) class))
854 ((not sb-pcl::standard-specializer)
855 nil)
857 (subtypep specl class)))))))
858 (map-into result #'(lambda (m)
859 (cons `(method ,(method-generic-function-name m))
860 (find-definition-source m)))
861 result))))
863 (defun canonicalize-class-designator (class-designator)
864 (typecase class-designator
865 (symbol (find-class class-designator nil))
866 (class class-designator)
867 (t nil)))
869 (defun method-generic-function-name (method)
870 (sb-mop:generic-function-name (sb-mop:method-generic-function method)))
872 (defun collect-specializing-methods (predicate)
873 (let ((result '()))
874 (sb-pcl::map-specializers
875 #'(lambda (specl)
876 (when (funcall predicate specl)
877 (let ((methods (sb-mop:specializer-direct-methods specl)))
878 (setf result (append methods result))))))
879 (delete-duplicates result)))
882 ;;;; ALLOCATION INTROSPECTION
884 (eval-when (:compile-toplevel :execute)
885 (defmacro pinnedp (addr)
886 `(eql (sb-alien:alien-funcall
887 (sb-alien:extern-alien "sb_introspect_pinnedp"
888 (function sb-alien:int sb-alien:unsigned))
889 ,addr)
890 1)))
892 (defun allocation-information (object)
893 "Returns information about the allocation of OBJECT. Primary return value
894 indicates the general type of allocation: :IMMEDIATE, :HEAP, :STACK,
895 or :FOREIGN.
897 Possible secondary return value provides additional information about the
898 allocation.
900 For :HEAP objects the secondary value is a plist:
902 :SPACE
903 Indicates the heap segment the object is allocated in.
905 :GENERATION
906 Is the current generation of the object: 0 for nursery, 6 for pseudo-static
907 generation loaded from core. (GENCGC and :SPACE :DYNAMIC only.)
909 :LARGE
910 Indicates a \"large\" object subject to non-copying
911 promotion. (GENCGC and :SPACE :DYNAMIC only.)
913 :BOXED
914 Indicates that the object is allocated in a boxed region. Unboxed
915 allocation is used for eg. specialized arrays after they have survived one
916 collection. (GENCGC and :SPACE :DYNAMIC only.)
918 :PINNED
919 Indicates that the page(s) on which the object resides are kept live due
920 to conservative references. Note that object may reside on a pinned page
921 even if :PINNED in NIL if the GC has not had the need to mark the the page
922 as pinned. (GENCGC and :SPACE :DYNAMIC only.)
924 :WRITE-PROTECTED
925 Indicates that the page on which the object starts is write-protected,
926 which indicates for :BOXED objects that it hasn't been written to since
927 the last GC of its generation. (GENCGC and :SPACE :DYNAMIC only.)
929 :PAGE
930 The index of the page the object resides on. (GENGC and :SPACE :DYNAMIC
931 only.)
933 For :STACK objects secondary value is the thread on whose stack the object is
934 allocated.
936 Expected use-cases include introspection to gain insight into allocation and
937 GC behaviour and restricting memoization to heap-allocated arguments.
939 Experimental: interface subject to change."
940 ;; FIXME: Would be nice to provide the size of the object as well, though
941 ;; maybe that should be a separate function, and something like MAP-PARTS
942 ;; for mapping over parts of arbitrary objects so users can get "deep sizes"
943 ;; as well if they want to.
945 (if (not (sb-vm:is-lisp-pointer (get-lisp-obj-address object)))
946 (values :immediate nil)
947 (let ((plist
948 (sb-sys:with-pinned-objects (object)
949 (let ((space (sb-ext:heap-allocated-p object)))
950 (when space
951 #+generational
952 (if (eq :dynamic space)
953 (symbol-macrolet ((page (sb-alien:deref sb-vm::page-table index)))
954 ;; No wonder #+big-endian failed introspection tests-
955 ;; bits are packed in the opposite order. And thankfully,
956 ;; this fix seems not to depend on whether the numbering
957 ;; scheme is MSB 0 or LSB 0, afaict.
958 (let* ((wp (page-protected-p object))
959 (index (sb-vm:find-page-index
960 (get-lisp-obj-address object)))
961 (type (sb-alien:slot page 'sb-vm::flags)))
962 (list :space space
963 :generation (sb-alien:slot page 'sb-vm::gen)
964 :write-protected wp
965 :boxed (> (logand type #xf) 1)
966 :pinned (pinnedp (get-lisp-obj-address object))
967 :large (logbitp 4 type)
968 :page index)))
969 (list :space space))
970 #-generational
971 (list :space space))))))
972 (cond (plist
973 (values :heap plist))
975 #+sb-thread
976 (let ((thread (sb-ext:stack-allocated-p object t)))
977 (when thread
978 (return-from allocation-information
979 (values :stack thread))))
980 #-sb-thread
981 (when (sb-vm:control-stack-pointer-valid-p
982 (sb-sys:int-sap (get-lisp-obj-address object)) nil)
983 (return-from allocation-information
984 (values :stack sb-thread::*current-thread*)))
985 :foreign)))))
987 (defun map-root (function object &key simple (ext t))
988 "Call FUNCTION with all non-immediate objects pointed to by OBJECT.
989 Returns OBJECT.
991 If SIMPLE is true (default is NIL), elides those pointers that are not
992 notionally part of certain built-in objects, but backpointers to a
993 conceptual parent: eg. elides the pointer from a SYMBOL to the
994 corresponding PACKAGE.
996 If EXT is true (default is T), includes some pointers that are not
997 actually contained in the object, but found in certain well-known
998 indirect containers: FDEFINITIONs, EQL specializers, classes, and
999 thread-local symbol values in other threads fall into this category.
1001 NOTE: calling MAP-ROOT with a THREAD does not currently map over
1002 conservative roots from the thread registers and interrupt contexts.
1004 Experimental: interface subject to change."
1005 (when (typep object '(or bignum float sb-sys:system-area-pointer
1006 fixnum character))
1007 (return-from map-root object))
1008 (let ((fun (coerce function 'function))
1009 (seen (alloc-xset)))
1010 (flet ((call (part)
1011 (when (and (sb-vm:is-lisp-pointer (get-lisp-obj-address part))
1012 (not (xset-member-p part seen)))
1013 (add-to-xset part seen)
1014 (funcall fun part))))
1015 (declare (dynamic-extent #'call))
1016 (when ext
1017 (multiple-value-bind (value foundp)
1018 (let ((table sb-pcl::*eql-specializer-table*))
1019 (with-system-mutex ((hash-table-lock table))
1020 (gethash object table)))
1021 (when foundp (call value))))
1022 (sb-vm:do-referenced-object (object call)
1023 (cons
1024 :extend
1025 (when (and ext (ignore-errors (fboundp object)))
1026 (call (fdefinition object))))
1027 (instance
1028 :extend
1029 #+sb-thread
1030 (when (typep object 'sb-thread:thread)
1031 (cond ((eq object sb-thread:*current-thread*)
1032 (dolist (value (sb-thread::%thread-local-references))
1033 (call value))
1034 (sb-vm::map-stack-references #'call))
1036 ;; KLUDGE: INTERRUPT-THREAD is Not Nice (tm), but
1037 ;; the alternative would be stopping the world...
1038 (let ((sem (sb-thread:make-semaphore))
1039 (refs nil))
1040 (handler-case
1041 (progn
1042 (sb-thread:interrupt-thread
1043 object
1044 (lambda ()
1045 (setf refs (sb-thread::%thread-local-references))
1046 (sb-vm::map-stack-references (lambda (x) (push x refs)))
1047 (sb-thread:signal-semaphore sem)))
1048 (sb-thread:wait-on-semaphore sem))
1049 (sb-thread:interrupt-thread-error ()))
1050 ;; This is whacky - the other thread signals our condition var,
1051 ;; *then* we call the funarg on objects that may no longer
1052 ;; satisfy VALID-TAGGED-POINTER-P.
1053 ;; And incidentally, we miss any references from TLS indices
1054 ;; that map onto the 'struct thread', which is just as well
1055 ;; since they're either fixnums or dynamic-extent objects.
1056 (mapc #'call refs))))))
1057 ((satisfies array-header-p)
1058 :override
1059 ;; The default implementation always scans %array-displaced-from
1060 (call (%array-data object))
1061 (call (%array-displaced-p object))
1062 (unless simple
1063 (call (%array-displaced-from object))))
1064 (code-component
1065 :extend
1066 (loop for i below (code-n-entries object)
1067 do (call (%code-entry-point object i))))
1068 (function ; excluding CLOSURE and FUNCALLABLE-INSTANCE
1069 :override
1070 (unless simple
1071 (call (fun-code-header object)))
1072 (call (%simple-fun-name object))
1073 (call (%simple-fun-arglist object))
1074 (call (%simple-fun-source object))
1075 (call (%simple-fun-info object)))
1076 (symbol
1077 ;; We use :override here because (apparently) the intent is
1078 ;; to avoid calling FUNCTION on the SYMBOL-PACKAGE
1079 ;; when SIMPLE is NIL (the default). And we skip SYMBOL-EXTRA for
1080 ;; the same reason that we don't call FUNCTION on SYMBOL-INFO
1081 ;; (logically it's "system" data, not for user consumption).
1082 ;; Frankly this entire function is a confusing mishmash that is not
1083 ;; accurate for computing a true graph of objects starting from a
1084 ;; certain point, given all the special cases that it implements.
1085 :override
1086 (when ext
1087 (dolist (thread (sb-thread:list-all-threads))
1088 (call (sb-thread:symbol-value-in-thread object thread nil))))
1089 (call (sb-sys:%primitive sb-c:fast-symbol-global-value object))
1090 ;; These first two are probably unnecessary.
1091 ;; The functoid values, if present, are in SYMBOL-INFO
1092 ;; which is traversed whether or not EXT was true.
1093 ;; But should we traverse SYMBOL-INFO?
1094 ;; I don't know what is expected of this interface.
1095 (when (and ext (ignore-errors (fboundp object)))
1096 (call (fdefinition object))
1097 (call (macro-function object))
1098 (let ((class (find-class object nil)))
1099 (when class (call class))))
1100 (call (symbol-plist object)) ; perhaps SB-KERNEL:SYMBOL-INFO instead?
1101 (call (symbol-name object))
1102 (unless simple
1103 (call (symbol-package object))))
1105 :extend
1106 (case (widetag-of object)
1107 (#.sb-vm:value-cell-widetag
1108 (call (value-cell-ref object)))
1110 (warn "~&MAP-ROOT: Unknown widetag ~S: ~S~%"
1111 (widetag-of object) object)))))))
1112 object)
1114 (defun object-size (object)
1115 (+ (primitive-object-size object)
1116 (typecase object
1117 (sb-mop:funcallable-standard-object
1118 (primitive-object-size (sb-pcl::fsc-instance-slots object)))
1119 (standard-object
1120 (primitive-object-size (sb-pcl::std-instance-slots object)))
1121 (t 0))))
1123 ;;; Print a distribution of object sizes in SPACE.
1124 ;;; There are two bins for cons-sized objects: conses and anything else,
1125 ;;; the latter including SAPs, value cells, 0-length simple-vectors,
1126 ;;; and a bunch of other things.
1127 (defun object-size-histogram (&optional
1128 (space :dynamic)
1129 (size-bins ; objects whose size in words is <= this
1130 `#(2 4 6 8 10 16 20 24 32 64 128 256 512 1024
1131 2048 4096 8192 16384 32768 131072 524288
1132 ,(ash 1 20) ,(ash 1 21) ,(ash 1 23))))
1133 (declare (simple-vector size-bins))
1134 (let* ((n-bins (+ (length size-bins) 2))
1135 (counts (make-array n-bins :initial-element 0))
1136 (size-totals (make-array n-bins :initial-element 0)))
1137 (sb-vm:map-allocated-objects
1138 (lambda (obj type size)
1139 (declare (ignore type))
1140 (cond ((consp obj)
1141 (incf (aref counts 0)))
1143 (let* ((words (ash size (- sb-vm:word-shift)))
1144 (bin
1145 (let ((i (position words size-bins :test #'<=)))
1146 (if i (1+ i) (1- n-bins)))))
1147 (incf (aref counts bin))
1148 (incf (aref size-totals bin) words)))))
1149 space)
1150 (format t " Freq Tot Words~% ========= =========~%")
1151 (dotimes (i n-bins)
1152 (format t " ~9d ~11d ~a~%"
1153 (aref counts i)
1154 (if (eql i 0) ; cons bin
1155 (* 2 (aref counts i))
1156 (aref size-totals i))
1157 (cond ((zerop i) "cons")
1158 ((eql i (1- n-bins))
1159 (format nil " > ~D" (aref size-bins (- n-bins 3))))
1161 (let ((this-bin-size (aref size-bins (1- i)))
1162 (prev-bin-size (when (>= i 2) (aref size-bins (- i 2)))))
1163 (format nil "~:[<=~;=~] ~D"
1164 (or (not prev-bin-size)
1165 (= this-bin-size (+ prev-bin-size 2)))
1166 this-bin-size))))))))
1168 (defun largest-objects (&key (threshold #+generational sb-vm:gencgc-page-bytes
1169 #-generational sb-c:+backend-page-bytes+)
1170 (sort :size))
1171 (declare (type (member :address :size) sort))
1172 (flet ((show-obj (obj)
1173 #-generational
1174 (format t "~10x ~7x ~s~%"
1175 (get-lisp-obj-address obj)
1176 (primitive-object-size obj)
1177 (type-of obj))
1178 #+generational
1179 (let* ((gen (generation-of obj))
1180 (page (sb-vm::find-page-index (sb-kernel:get-lisp-obj-address obj)))
1181 (flags (if (>= page 0)
1182 (sb-alien:slot (sb-alien:deref sb-vm:page-table page)
1183 'sb-vm::flags))))
1184 (format t "~10x ~7x ~a ~:[ ~;~:*~8b~] ~s~%"
1185 (get-lisp-obj-address obj)
1186 (primitive-object-size obj)
1187 (if gen gen #\?)
1188 flags
1189 (type-of obj)))))
1190 (case sort
1191 (:address
1192 (sb-vm:map-allocated-objects
1193 (lambda (obj widetag size)
1194 (declare (ignore widetag))
1195 (when (>= size threshold)
1196 (show-obj obj)))
1197 :all))
1198 (:size
1199 (let (list)
1200 (sb-vm:map-allocated-objects
1201 (lambda (obj widetag size)
1202 (declare (ignore widetag))
1203 (when (>= size threshold)
1204 (push obj list)))
1205 :all)
1206 (mapc #'show-obj
1207 (stable-sort list #'> :key #'primitive-object-size))
1208 nil)))))