Improve survived_gc_yet()
[sbcl.git] / src / code / show.lisp
blobe3bc0ba4a4cafdcf88a7568a4a4037292ee9311a
1 ;;;; some stuff for displaying information for debugging/experimenting
2 ;;;; with the system, mostly conditionalized with #!+SB-SHOW
4 ;;;; This software is part of the SBCL system. See the README file for
5 ;;;; more information.
6 ;;;;
7 ;;;; This software is derived from the CMU CL system, which was
8 ;;;; written at Carnegie Mellon University and released into the
9 ;;;; public domain. The software is in the public domain and is
10 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
11 ;;;; files for more information.
13 (in-package "SB!INT")
15 ;;;; various SB-SHOW-dependent forms
16 ;;;;
17 ;;;; In general, macros named /FOO
18 ;;;; * are for debugging/tracing
19 ;;;; * expand into nothing unless :SB-SHOW is in the target
20 ;;;; features list
21 ;;;; Often, they also do nothing at runtime if */SHOW* is NIL, but
22 ;;;; this is not always true for some very-low-level ones.
23 ;;;;
24 ;;;; (I follow the "/FOO for debugging/tracing expressions" naming
25 ;;;; rule and several other naming conventions in all my Lisp
26 ;;;; programming when possible, and then set Emacs to display comments
27 ;;;; in one shade of blue, tracing expressions in another shade of
28 ;;;; blue, and declarations and assertions in a yellowish shade, so
29 ;;;; that it's easy to separate them from the "real code" which
30 ;;;; actually does the work of the program. -- WHN 2001-05-07)
32 ;;; Set this to NIL to suppress output from /SHOW-related forms.
33 #!+sb-show (defvar */show* t)
35 #!+sb-show
36 (defmacro cannot-/show (string)
37 (declare (type simple-string string))
38 (declare (notinline concatenate))
39 #+sb-xc-host `(error "can't /SHOW: ~A" ,string)
40 ;; We end up in this situation when we execute /SHOW too early in
41 ;; cold init. That happens to me often enough that it's really
42 ;; annoying for it to cause a hard failure -- which at that point is
43 ;; hard to recover from -- instead of just diagnostic output.
44 #-sb-xc-host
45 `(progn (%primitive print
46 ,(concatenate 'simple-base-string "/can't /SHOW:" string))
47 t))
49 ;;; Should /SHOW output be suppressed at this point?
50 ;;;
51 ;;; Note that despite the connoting-no-side-effects-pure-predicate
52 ;;; name, we emit some error output if we're called at a point where
53 ;;; /SHOW is inherently invalid.
54 #!+sb-show
55 (defun suppress-/show-p ()
56 ;; protection against /SHOW too early in cold init for
57 ;; (FORMAT *TRACE-OUTPUT* ..) to work, part I: Obviously
58 ;; we need *TRACE-OUTPUT* bound.
59 (if (not (boundp '*trace-output*))
60 (cannot-/show "*TRACE-OUTPUT* isn't bound. (Try /SHOW0.)")
61 ;; ordinary, healthy reason to suppress /SHOW, no error
62 ;; output needed. Assume by default _not_ to suppress.
63 (and (boundp '*/show*) (not */show*))))
66 #!+(and sb-show (host-feature sb-xc))
67 (declaim (special *print-pretty*))
69 ;;; shorthand for a common idiom in output statements used in
70 ;;; debugging: (/SHOW "Case 2:" X Y) becomes a pretty-printed version
71 ;;; of (FORMAT .. "~&/Case 2: X=~S Y=~S~%" X Y), conditional on */SHOW*.
72 (defmacro /show (&rest xlist)
73 #!-sb-show (declare (ignore xlist))
74 #!+sb-show
75 (flet (;; Is X something we want to just show literally by itself?
76 ;; (instead of showing it as NAME=VALUE)
77 (literal-p (x) (or (stringp x) (numberp x))))
78 ;; We build a FORMAT statement out of what we find in XLIST.
79 (let ((format-stream (make-string-output-stream)) ; string arg to FORMAT
80 (format-reverse-rest) ; reversed &REST argument to FORMAT
81 (first-p t)) ; first pass through loop?
82 (write-string "~&~<~;/" format-stream)
83 (dolist (x xlist)
84 (if first-p
85 (setq first-p nil)
86 (write-string #+ansi-cl " ~_"
87 #-ansi-cl " " ; for CLISP (CLTL1-ish)
88 format-stream))
89 (if (literal-p x)
90 (princ x format-stream)
91 (progn (let ((*print-pretty* nil))
92 (format format-stream "~S=~~S" x))
93 (push x format-reverse-rest))))
94 (write-string "~;~:>~%" format-stream)
95 (let ((format-string (get-output-stream-string format-stream))
96 (format-rest (reverse format-reverse-rest)))
97 `(locally
98 (declare (optimize (speed 1) (space 2) (safety 3)))
99 (unless (suppress-/show-p)
100 (format *trace-output*
101 ,format-string
102 #+ansi-cl (list ,@format-rest)
103 #-ansi-cl ,@format-rest)) ; for CLISP (CLTL1-ish)
104 (values))))))
106 ;;; a disabled-at-compile-time /SHOW, implemented as a macro instead
107 ;;; of a function so that leaving occasionally-useful /SHOWs in place
108 ;;; but disabled incurs no run-time overhead and works even when the
109 ;;; arguments can't be evaluated (e.g. because they're only meaningful
110 ;;; in a debugging version of the system, or just due to bit rot..)
111 (defmacro /noshow (&rest rest)
112 (declare (ignore rest)))
114 ;;; like /SHOW, except displaying values in hexadecimal
115 (defmacro /xhow (&rest rest)
116 `(let ((*print-base* 16))
117 (/show ,@rest)))
118 (defmacro /noxhow (&rest rest)
119 (declare (ignore rest)))
121 ;;; a trivial version of /SHOW which only prints a constant string,
122 ;;; implemented at a sufficiently low level that it can be used early
123 ;;; in cold init
125 ;;; Unlike the other /SHOW-related functions, this one doesn't test
126 ;;; */SHOW* at runtime, because messing with special variables early
127 ;;; in cold load is too much trouble to be worth it.
128 (defmacro /show0 (&rest string-designators)
129 ;; We don't inline CONCATENATE, because some of the
130 ;; machinery behind its optimizations isn't available in the
131 ;; cross-compiler.
132 (declare (notinline concatenate))
133 (let ((s (apply #'concatenate
134 'simple-string
135 (mapcar #'string string-designators))))
136 (declare (ignorable s)) ; (for when #!-SB-SHOW)
137 #+sb-xc-host `(/show ,s)
138 #-sb-xc-host `(progn
139 #!+sb-show
140 (%primitive print
141 ,(concatenate 'simple-string "/" s)))))
142 (defmacro /noshow0 (&rest rest)
143 (declare (ignore rest)))
145 ;;; low-level display of a string, works even early in cold init
146 (defmacro /primitive-print (thing)
147 (declare (ignorable thing)) ; (for when #!-SB-SHOW)
148 #!+sb-show
149 (progn
150 #+sb-xc-host `(/show "(/primitive-print)" ,thing)
151 #-sb-xc-host `(%primitive print (the simple-string ,thing))))
153 ;;; low-level display of a system word, works even early in cold init
154 (defmacro /hexstr (thing)
155 (declare (ignorable thing)) ; (for when #!-SB-SHOW)
156 #!+sb-show
157 (progn
158 #+sb-xc-host `(/show "(/hexstr)" ,thing)
159 #-sb-xc-host `(%primitive print (hexstr ,thing))))
161 (defmacro /nohexstr (thing)
162 (declare (ignore thing)))
164 (/show0 "done with show.lisp")