1 ;;;; This file provides a functional interface to global information
2 ;;;; about named things in the system. Information is considered to be
3 ;;;; global if it must persist between invocations of the compiler. The
4 ;;;; use of a functional interface eliminates the need for the compiler
5 ;;;; to worry about the actual representation. This is important, since
6 ;;;; the information may well have several representations.
8 ;;;; The database contains arbitrary Lisp values, addressed by a
9 ;;;; combination of Name, Class and Type. The Name is an EQUAL-thing
10 ;;;; which is the name of the thing we are recording information
11 ;;;; about. Class is the kind of object involved. Typical classes are
12 ;;;; :FUNCTION, :VARIABLE, :TYPE, ... A Type names a particular piece
13 ;;;; of information within a given class. Class and Type are keywords,
14 ;;;; and are compared with EQ.
16 ;;;; The relation between this file and 'info-vectors' is that the
17 ;;;; latter provides a fundamental mechanism to create property-list-like
18 ;;;; things whose "indicators" are restricted to small integers
19 ;;;; and whose values are anything; whereas the globaldb provides the
20 ;;;; facility of looking up the properties by keyword, a/k/a Class+Type.
21 ;;;; The keyword regime is somewhat arbitrary because ultimately the
22 ;;;; pair of keywords just translates to a small integer, usually
23 ;;;; resolvable at compile-time for the most part.
25 ;;;; This software is part of the SBCL system. See the README file for
26 ;;;; more information.
28 ;;;; This software is derived from the CMU CL system, which was
29 ;;;; written at Carnegie Mellon University and released into the
30 ;;;; public domain. The software is in the public domain and is
31 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
32 ;;;; files for more information.
36 (!begin-collecting-cold-init-forms
)
37 #!+sb-show
(!cold-init-forms
(/show0
"early in globaldb.lisp cold init"))
39 ;;; The DEFVAR for this appears later.
41 (declaim (special *universal-type
*))
43 ;;; This is sorta semantically equivalent to SXHASH, but better-behaved for
44 ;;; legal function names. It performs more work by not cutting off as soon
45 ;;; in the CDR direction, thereby improving the distribution of method names.
46 ;;; More work here equates to less work in the global hashtable.
47 ;;; To wit: (eq (sxhash '(foo a b c bar)) (sxhash '(foo a b c d))) => T
48 ;;; but the corresponding globaldb-sxhashoids differ.
49 ;;; This is no longer inline because for the cases where it is needed -
50 ;;; names which are not just symbols or (SETF F) - an extra call has no impact.
51 (defun globaldb-sxhashoid (name)
52 ;; we can't use MIX because it's in 'target-sxhash',
53 ;; so use the host's sxhash, but ensure that the result is a target fixnum.
54 #+sb-xc-host
(logand (sxhash name
) sb
!xc
:most-positive-fixnum
)
57 (declare (optimize (safety 0))) ; after the argc check
58 ;; TRAVERSE will walk across more cons cells than RECURSE will descend.
59 ;; That's why this isn't just one self-recursive function.
60 (labels ((traverse (accumulator x length-limit
)
61 (declare (fixnum length-limit
))
62 (cond ((atom x
) (sb!int
:mix
(sxhash x
) accumulator
))
63 ((zerop length-limit
) accumulator
)
64 (t (traverse (sb!int
:mix
(recurse (car x
) 4) accumulator
)
65 (cdr x
) (1- length-limit
)))))
66 (recurse (x depthoid
) ; depthoid = a blend of level and length
67 (declare (fixnum depthoid
))
68 (cond ((atom x
) (sxhash x
))
69 ((zerop depthoid
) #xdeadbeef
)
70 (t (sb!int
:mix
(recurse (car x
) (1- depthoid
))
71 (recurse (cdr x
) (1- depthoid
)))))))
72 (traverse 0 name
10))))
74 ;;; Given any non-negative integer, return a prime number >= to it.
76 ;;; FIXME: This logic should be shared with ALMOST-PRIMIFY in
77 ;;; hash-table.lisp. Perhaps the merged logic should be
78 ;;; PRIMIFY-HASH-TABLE-SIZE, implemented as a lookup table of primes
79 ;;; after integral powers of two:
80 ;;; #(17 37 67 131 ..)
81 ;;; (Or, if that's too coarse, after half-integral powers of two.) By
82 ;;; thus getting rid of any need for primality testing at runtime, we
83 ;;; could punt POSITIVE-PRIMEP, too.
85 (declare (type unsigned-byte x
))
86 (do ((n (logior x
1) (+ n
2)))
87 ((positive-primep n
) n
)))
89 ;;;; info classes, info types, and type numbers, part I: what's needed
90 ;;;; not only at compile time but also at run time
92 ;;;; Note: This section is a blast from the past, a little trip down
93 ;;;; memory lane to revisit the weird host/target interactions of the
94 ;;;; CMU CL build process. Because of the way that the cross-compiler
95 ;;;; and target compiler share stuff here, if you change anything in
96 ;;;; here, you'd be well-advised to nuke all your fasl files and
97 ;;;; restart compilation from the very beginning of the bootstrap
100 ;;; Why do we suppress the :COMPILE-TOPLEVEL situation here when we're
101 ;;; running the cross-compiler? The cross-compiler (which was built
102 ;;; from these sources) has its version of these data and functions
103 ;;; defined in the same places we'd be defining into. We're happy with
104 ;;; its version, since it was compiled from the same sources, so
105 ;;; there's no point in overwriting its nice compiled version of this
106 ;;; stuff with our interpreted version. (And any time we're *not*
107 ;;; happy with its version, perhaps because we've been editing the
108 ;;; sources partway through bootstrapping, tch tch, overwriting its
109 ;;; version with our version would be unlikely to help, because that
110 ;;; would make the cross-compiler very confused.)
111 (eval-when (#-sb-xc
:compile-toplevel
:load-toplevel
:execute
)
113 ;;; a map from type numbers to TYPE-INFO objects. There is one type
114 ;;; number for each defined CLASS/TYPE pair.
116 ;;; We build its value at build-the-cross-compiler time (with calls to
117 ;;; DEFINE-INFO-TYPE), then generate code to recreate the compile time
118 ;;; value, and arrange for that code to be called in cold load.
119 ;;; KLUDGE: We don't try to reset its value when cross-compiling the
120 ;;; compiler, since that creates too many bootstrapping problems,
121 ;;; instead just reusing the built-in-the-cross-compiler version,
122 ;;; which is theoretically a little bit ugly but pretty safe in
123 ;;; practice because the cross-compiler is as close to the target
124 ;;; compiler as we can make it, i.e. identical in most ways, including
125 ;;; this one. -- WHN 2001-08-19
126 (declaim (type (simple-vector #.
(ash 1 type-number-bits
)) *info-types
*))
127 (defglobal *info-types
* (make-array (ash 1 type-number-bits
) :initial-element nil
))
129 (defstruct (type-info
130 #-no-ansi-print-object
131 (:print-object
(lambda (x s
)
132 (print-unreadable-object (x s
)
137 (type-info-number x
)))))
139 make-globaldb-info-metadata
(number class name type-spec
))
141 ;; the name of this type
142 (name nil
:type keyword
)
144 (class nil
:type keyword
)
145 ;; a number that uniquely identifies this type (and implicitly its class)
146 (number nil
:type type-number
)
147 ;; a type specifier which info of this type must satisfy
148 (type-spec nil
:type t
)
149 ;; If FUNCTIONP, then a function called when there is no information of
150 ;; this type. If not FUNCTIONP, then any object serving as a default.
152 ;; Two functions called by (SETF INFO) before calling SET-INFO-VALUE.
153 ;; Regarding the type specifiers on these slots, I wanted to write them
154 ;; as (SFUNCTION (T) T) for documentation - and it elides the check for
155 ;; multiple values returned - but doing that causes failure building the
156 ;; cross-compiler under CMUCL 20c because it tries to call TYPEP on that,
157 ;; and complains that it can't.
158 ;; 1. A function that type-checks its argument and returns it,
159 ;; or signals an error.
160 (type-checker #'identity
:type function
)
161 ;; 2. a function of two arguments, a name and new-value, which performs
162 ;; any other checks and/or side-effects including signaling an error.
163 (validate-function nil
:type
(or function null
)))
164 (declaim (freeze-type type-info
))
166 (defconstant +info-metainfo-type-num
+ 0)
168 ;; Perform the equivalent of (GET-INFO-VALUE sym +INFO-METAINFO-TYPE-NUM+)
169 ;; but without the AVER that metadata already exists, and bypassing the
171 (defun %get-type-info-metadata
(sym)
172 (let* ((info-vector (symbol-info-vector sym
))
173 (index (if info-vector
174 (packed-info-value-index info-vector
+no-auxilliary-key
+
175 +info-metainfo-type-num
+))))
176 (if index
(svref info-vector index
))))
178 ;; Find or create a TYPE-INFO object designated by CLASS- and TYPE-KEYWORD.
179 ;; If not found, the specified TYPE-NUM and TYPE-SPEC are used to
180 ;; initialize it. If TYPE-NUM is -1, the next available number is assigned.
181 ;; Return the new type-num.
182 (defun register-info-metadata (type-num class-keyword type-keyword type-spec
)
183 (let ((metainfo (find-type-info class-keyword type-keyword
)))
184 (cond (metainfo) ; Do absolutely positively nothing.
186 (when (eql type-num -
1) ; pick a new type-num
187 ;; The zeroth type-num is reserved for INFO's own private use.
188 ;; +fdefn-type-num+ is also reserved and must be special-cased.
189 ;; Generalizing DEFINE-INFO-TYPE to optionally pass a type-number
190 ;; would also mean changing the fact that a specified number is
191 ;; used only for restoring *INFO-TYPES* during cold-init.
193 (or (if (and (eq class-keyword
:function
)
194 (eq type-keyword
:definition
))
196 (position nil
*info-types
* :start
1))
197 (error "no more INFO type numbers available"))))
198 (setf metainfo
(make-globaldb-info-metadata
199 type-num class-keyword type-keyword type-spec
)
200 (aref *info-types
* type-num
) metainfo
)
201 (let ((list (%get-type-info-metadata type-keyword
)))
203 type-keyword
+info-metainfo-type-num
+
204 (cond ((not list
) metainfo
) ; unique, just store it
205 ((listp list
) (cons metainfo list
)) ; prepend to the list
206 (t (list metainfo list
))))))) ; convert atom to a list
207 (type-info-number metainfo
)))
209 ;; If CLASS-KEYWORD/TYPE-KEYWORD designate an info-type,
210 ;; return the corresponding TYPE-INFO object, otherwise NIL.
211 (defun find-type-info (class-keyword type-keyword
)
212 (declare (type keyword class-keyword type-keyword
))
213 (let ((metadata (%get-type-info-metadata type-keyword
)))
214 ;; Most TYPE-KEYWORDs uniquely designate an object, so we store only that.
215 ;; Otherwise we store a list which has a small handful of (<= 4) items.
216 (cond ((listp metadata
)
217 ;; Can we *please* make (FIND ...) not call GENERIC+
218 ;; so that I don't feel compelled to express this as a DOLIST ?
219 (dolist (info metadata nil
)
220 (when (eq (type-info-class (truly-the type-info info
))
223 ((eq (type-info-class (truly-the type-info metadata
)) class-keyword
)
226 (declaim (ftype (function (keyword keyword
) type-info
) type-info-or-lose
))
227 (defun type-info-or-lose (class type
)
228 #+sb-xc
(/noshow0
"entering TYPE-INFO-OR-LOSE, CLASS,TYPE=..")
229 #+sb-xc
(/nohexstr class
)
230 #+sb-xc
(/nohexstr type
)
231 (or (find-type-info class type
)
232 (error "(~S ~S) is not a defined info type." class type
)))
236 ;;;; info types, and type numbers, part II: what's
237 ;;;; needed only at compile time, not at run time
239 (eval-when (:compile-toplevel
:execute
)
241 ;;; a list of forms for initializing the DEFAULT slots of TYPE-INFO
242 ;;; objects, accumulated during compilation and eventually converted
243 ;;; into a function to be called at cold load time after the
244 ;;; appropriate TYPE-INFO objects have been created
246 ;;; Note: This is quite similar to the !COLD-INIT-FORMS machinery, but
247 ;;; we can't conveniently use the ordinary !COLD-INIT-FORMS machinery
248 ;;; here. The problem is that the natural order in which the
249 ;;; default-slot-initialization forms are generated relative to the
250 ;;; order in which the TYPE-INFO-creation forms are generated doesn't
251 ;;; match the relative order in which the forms need to be executed at
253 (defparameter *!reversed-type-info-init-forms
* nil
)
255 ;;; Define a new type of global information.
256 ;;; CLASS/TYPE form a two-piece name for the kind of information,
257 ;;; DEFAULT is a defaulting expression, and TYPE-SPEC
258 ;;; is a type specifier which values of the type must satisfy.
259 ;;; Roughly speaking there is a hierarchy to the two-piece names
260 ;;; but this is a fiction that is not maintained anywhere in the internals.
262 ;;; If the defaulting expression's value is a function, it is called with
263 ;;; the name for which the information is being looked up; otherwise it is
264 ;;; taken as the default value. The defaulting expression is used each time
265 ;;; a value is needed when one hasn't been previously set. (The result
266 ;;; does not automatically become the new value for the piece of info.)
267 ;;; Should a default value be itself a function, this must be expressed as
268 ;;; :DEFAULT (CONSTANTLY #'<a-function-name>) to adhere to the convention
269 ;;; that default objects satisfying FUNCTIONP will always be funcalled.
271 ;;; The main thing we do is determine the type's number. We need to do
272 ;;; this at macroexpansion time, since both the COMPILE and LOAD time
273 ;;; calls to %DEFINE-INFO-TYPE must use the same type number.
274 (#+sb-xc-host defmacro
275 #-sb-xc-host sb
!xc
:defmacro
276 define-info-type
((class type
)
277 &key
(type-spec (missing-arg))
280 (declare (type keyword class type
))
282 (eval-when (:compile-toplevel
:execute
)
283 ;; At compile time, ensure that the type number exists. It will
284 ;; need to be forced to exist at cold load time, too, but
285 ;; that's not handled here; it's handled by later code which
286 ;; looks at the compile time state and generates code to
287 ;; replicate it at cold load time.
288 (let ((num (register-info-metadata -
1 ,class
,type
',type-spec
)))
289 ;; Arrange for TYPE-INFO-DEFAULT, TYPE-INFO-TYPE-CHECKER, and
290 ;; TYPE-INFO-VALIDATE-FUNCTION to be set at cold load
291 ;; time. (They can't very well be set at cross-compile time,
292 ;; since they differ between host and target and are
293 ;; host-compiled closures.)
294 (push `(let ((type-info (aref *info-types
* ,num
)))
295 ;; cold-init can't actually AVER without crashing hard,
296 ;; but what the heck, let's do it.
298 ,@',(unless (eq type-spec
't
)
299 ;; avoid re-inventing #'IDENTITY N times over
300 `((setf (type-info-type-checker type-info
)
301 (lambda (x) (declare (type ,type-spec x
)) x
))))
302 (setf (type-info-validate-function type-info
)
304 (type-info-default type-info
) ,',default
))
305 *!reversed-type-info-init-forms
*)))
311 ;;; INFO is the standard way to access the database. It's settable.
313 ;;; Return the information of the specified TYPE and CLASS for NAME.
314 ;;; The second value returned is true if there is any such information
315 ;;; recorded. If there is no information, the first value returned is
316 ;;; the default and the second value returned is NIL.
317 (defun info (class type name
)
318 (let ((info (type-info-or-lose class type
)))
319 (get-info-value name
(type-info-number info
))))
321 (defun (setf info
) (new-value class type name
)
322 (let ((info (type-info-or-lose class type
)))
323 (funcall (type-info-type-checker info
) new-value
)
324 (awhen (type-info-validate-function info
)
325 (funcall it name new-value
))
326 (set-info-value name
(type-info-number info
) new-value
)))
328 ;;; Clear the information of the specified TYPE and CLASS for NAME in
329 ;;; the current environment. Return true if there was any info.
330 (defun clear-info (class type name
)
331 (let ((info (type-info-or-lose class type
)))
332 (clear-info-value name
(type-info-number info
))))
334 (defun clear-info-value (name type
)
335 (declare (type type-number type
))
336 ;; A call to UNCROSS was suspiciously absent, so I added this ERROR
337 ;; to be certain that it's not supposed to happen when building the xc.
338 #+sb-xc-xhost
(error "Strange CLEAR-INFO building the xc: ~S ~S" name type
)
340 (with-globaldb-name (key1 key2
) name
342 ;; If PACKED-INFO-REMOVE has nothing to do, it returns NIL,
343 ;; corresponding to the input that UPDATE-SYMBOL-INFO expects.
344 (dx-flet ((clear-simple (old)
345 (setq new
(packed-info-remove old key2 type
))))
346 (update-symbol-info key1
#'clear-simple
))
348 ;; The global hashtable is not imbued with knowledge of the convention
349 ;; for PACKED-INFO-REMOVE because that would render it less useful
350 ;; as a general-purpose global hashtable for other kinds of stuff
351 ;; that I might want it to store aside from packed infos.
352 ;; So here UPDATE might receive NIL but must not return NIL if
353 ;; there was a non-nil input. NIL doesn't mean "do nothing".
354 (dx-flet ((clear-hairy (old)
356 ;; if -REMOVE => nil, then update NEW but return OLD
357 (or (setq new
(packed-info-remove
358 old
+no-auxilliary-key
+ type
))
360 (info-puthash *info-environment
* name
#'clear-hairy
)))
363 ;;;; *INFO-ENVIRONMENT*
366 (setq *info-environment
* (make-info-hashtable))
367 (/show0
"done setting *INFO-ENVIRONMENT*"))
371 ;;; Return the value of NAME / TYPE-NUMBER from the global environment,
372 ;;; or return the default if there is no global info.
373 ;;; The secondary value indicates whether info was found vs defaulted.
374 (declaim (ftype (sfunction (t type-number
) (values t boolean
))
376 (defun get-info-value (name type-number
)
377 ;; sanity check: If we have screwed up initialization somehow, then
378 ;; *INFO-TYPES* could still be uninitialized at the time we try to
379 ;; get an info value, and then we'd be out of luck. (This happened,
380 ;; and was confusing to debug, when rewriting EVAL-WHEN in
382 (let ((metainfo (aref *info-types
* type-number
)))
384 (multiple-value-bind (vector aux-key
)
385 (let ((name (uncross name
)))
386 (with-globaldb-name (key1 key2
) name
387 :simple
(values (symbol-info-vector key1
) key2
)
388 :hairy
(values (info-gethash name
*info-environment
*)
389 +no-auxilliary-key
+)))
392 (packed-info-value-index vector aux-key type-number
)))
394 (return-from get-info-value
(values (svref vector index
) t
))))))
395 (let ((val (type-info-default metainfo
)))
396 (values (if (functionp val
) (funcall val name
) val
) nil
))))
398 ;; Perform the approximate equivalent operations of retrieving
399 ;; (INFO :CLASS :TYPE NAME), but if no info is found, invoke CREATION-FORM
400 ;; to produce an object that becomes the value for that piece of info, storing
401 ;; and returning it. The entire sequence behaves atomically but with a proviso:
402 ;; the creation form's result may be discarded, and another object returned
403 ;; instead (presumably) from another thread's execution of the creation form.
404 ;; If constructing the object has either non-trivial cost, or deleterious
405 ;; side-effects from making and discarding its result, do NOT use this macro.
406 ;; A mutex-guarded table would probably be more appropriate in such cases.
408 (def!macro get-info-value-initializing
(info-class info-type name creation-form
)
409 (with-unique-names (type-number proc
)
411 ,(if (and (keywordp info-type
) (keywordp info-class
))
412 (type-info-number (type-info-or-lose info-class info-type
))
414 (type-info-or-lose ,info-class
,info-type
)))))
415 (dx-flet ((,proc
() ,creation-form
))
416 (%get-info-value-initializing
,name
,type-number
#',proc
)))))
418 ;; Call FUNCTION once for each Name in globaldb that has information associated
419 ;; with it, passing the function the Name as its only argument.
421 (defun call-with-each-globaldb-name (function)
422 (let ((name (list nil nil
)) ; preallocate just one, and mutate as we go
423 (function (%coerce-callable-to-fun function
)))
424 (dolist (package (list-all-packages))
425 (do-symbols (symbol package
)
426 (when (eq (symbol-package symbol
) package
)
427 (let ((vector (symbol-info-vector symbol
)))
429 ;; Check whether SYMBOL has info for itself
430 (when (plusp (packed-info-field vector
0 0))
431 (funcall function symbol
))
432 ;; Now deal with (<othersym> SYMBOL) names
433 (do-packed-info-vector-aux-key (vector key-index
)
434 (progn (setf (first name
) (svref vector key-index
)
435 (second name
) symbol
)
436 (funcall function name
))))))))
437 (info-maphash (lambda (name data
)
438 (declare (ignore data
))
439 (funcall function name
))
440 *info-environment
*)))
442 ;;;; ":FUNCTION" subsection - Data pertaining to globally known functions.
444 ;; must be info type number 1
445 (define-info-type (:function
:definition
) :type-spec
(or fdefn null
))
446 (eval-when (:compile-toplevel
)
447 (aver (= (type-info-number (type-info-or-lose :function
:definition
))
450 ;;; the kind of functional object being described. If null, NAME isn't
451 ;;; a known functional object.
452 (define-info-type (:function
:kind
)
453 :type-spec
(member nil
:function
:macro
:special-form
)
454 ;; I'm a little confused what the correct behavior of this default
455 ;; is. It's not clear how to generalize the FBOUNDP expression to
456 ;; the cross-compiler. As far as I can tell, NIL is a safe default
457 ;; -- it might keep the compiler from making some valid
458 ;; optimization, but it shouldn't produce incorrect code. -- WHN
462 #-sb-xc-host
(lambda (name) (if (fboundp name
) :function nil
)))
464 ;;; The type specifier for this function.
465 (define-info-type (:function
:type
)
467 ;; Again (as in DEFINE-INFO-TYPE :CLASS :FUNCTION :TYPE :KIND) it's
468 ;; not clear how to generalize the FBOUNDP expression to the
469 ;; cross-compiler. -- WHN 19990330
471 ;; Delay evaluation of (SPECIFIER-TYPE) since it can't work yet
472 #+sb-xc-host
(lambda (x) (declare (ignore x
)) (specifier-type 'function
))
473 #-sb-xc-host
(lambda (name)
475 (handler-bind ((style-warning #'muffle-warning
))
476 (specifier-type (sb!impl
::%fun-type
(fdefinition name
))))
477 (specifier-type 'function
))))
479 ;;; the ASSUMED-TYPE for this function, if we have to infer the type
480 ;;; due to not having a declaration or definition
481 (define-info-type (:function
:assumed-type
)
482 ;; FIXME: The type-spec really should be
483 ;; (or approximate-fun-type null)).
484 ;; It was changed to T as a hopefully-temporary hack while getting
485 ;; cold init problems untangled.
488 ;;; where this information came from:
489 ;;; :ASSUMED = from uses of the object
490 ;;; :DEFINED = from examination of the definition
491 ;;; :DEFINED-METHOD = implicit, incremental declaration by CLOS.
492 ;;; :DECLARED = from a declaration
493 ;;; :DEFINED trumps :ASSUMED, :DEFINED-METHOD trumps :DEFINED,
494 ;;; and :DECLARED trumps :DEFINED-METHOD.
495 ;;; :DEFINED and :ASSUMED are useful for issuing compile-time warnings,
496 ;;; :DEFINED-METHOD and :DECLARED are useful for ANSIly specializing
497 ;;; code which implements the function, or which uses the function's
499 (define-info-type (:function
:where-from
)
500 :type-spec
(member :declared
:defined-method
:assumed
:defined
)
502 ;; Again (as in DEFINE-INFO-TYPE :CLASS :FUNCTION :TYPE :KIND) it's
503 ;; not clear how to generalize the FBOUNDP expression to the
504 ;; cross-compiler. -- WHN 19990606
505 #+sb-xc-host
:assumed
506 #-sb-xc-host
(lambda (name) (if (fboundp name
) :defined
:assumed
)))
508 ;;; something which can be decoded into the inline expansion of the
509 ;;; function, or NIL if there is none
511 ;;; To inline a function, we want a lambda expression, e.g.
512 ;;; '(LAMBDA (X) (+ X 1)). That can be encoded here in one of two
514 ;;; * The value in INFO can be the lambda expression itself, e.g.
515 ;;; (SETF (INFO :FUNCTION :INLINE-EXPANSION-DESIGNATOR 'FOO)
516 ;;; '(LAMBDA (X) (+ X 1)))
517 ;;; This is the ordinary way, the natural way of representing e.g.
518 ;;; (DECLAIM (INLINE FOO))
519 ;;; (DEFUN FOO (X) (+ X 1))
520 ;;; * The value in INFO can be a closure which returns the lambda
522 ;;; (SETF (INFO :FUNCTION :INLINE-EXPANSION-DESIGNATOR 'BAR-LEFT-CHILD)
524 ;;; '(LAMBDA (BAR) (BAR-REF BAR 3))))
525 ;;; This twisty way of storing values is supported in order to
526 ;;; allow structure slot accessors, and perhaps later other
527 ;;; stereotyped functions, to be represented compactly.
528 (define-info-type (:function
:inline-expansion-designator
)
529 :type-spec
(or list function
))
531 ;;; This specifies whether this function may be expanded inline. If
532 ;;; null, we don't care.
533 (define-info-type (:function
:inlinep
) :type-spec inlinep
)
535 ;;; a macro-like function which transforms a call to this function
536 ;;; into some other Lisp form. This expansion is inhibited if inline
537 ;;; expansion is inhibited
538 (define-info-type (:function
:source-transform
) :type-spec
(or function null
))
540 ;;; the macroexpansion function for this macro
541 (define-info-type (:function
:macro-function
) :type-spec
(or function null
))
543 ;;; the compiler-macroexpansion function for this macro
544 (define-info-type (:function
:compiler-macro-function
)
545 :type-spec
(or function null
))
547 ;;; a function which converts this special form into IR1
548 (define-info-type (:function
:ir1-convert
) :type-spec
(or function null
))
550 ;;; If a function is "known" to the compiler, then this is a FUN-INFO
551 ;;; structure containing the info used to special-case compilation.
552 (define-info-type (:function
:info
) :type-spec
(or fun-info null
))
554 (define-info-type (:function
:structure-accessor
)
555 :type-spec
(or defstruct-description null
))
557 ;;;; ":VARIABLE" subsection - Data pertaining to globally known variables.
559 ;;; the kind of variable-like thing described
560 (define-info-type (:variable
:kind
)
561 :type-spec
(member :special
:constant
:macro
:global
:alien
:unknown
)
562 :default
(lambda (name)
563 (if (typep name
'(or boolean keyword
))
567 (define-info-type (:variable
:always-bound
)
568 :type-spec
(member nil
:eventually
:always-bound
))
570 (define-info-type (:variable
:deprecated
) :type-spec t
)
572 ;;; the declared type for this variable
573 (define-info-type (:variable
:type
)
575 ;; Delay evaluation of *UNIVERSAL-TYPE* since it can't work yet
576 :default
(lambda (x) (declare (ignore x
)) *universal-type
*))
578 ;;; where this type and kind information came from
579 (define-info-type (:variable
:where-from
)
580 :type-spec
(member :declared
:assumed
:defined
) :default
:assumed
)
582 ;;; the macro-expansion for symbol-macros
583 (define-info-type (:variable
:macro-expansion
) :type-spec t
)
585 (define-info-type (:variable
:alien-info
)
586 :type-spec
(or heap-alien-info null
))
588 (define-info-type (:variable
:documentation
) :type-spec
(or string null
))
590 ;; :WIRED-TLS describes how SYMBOL-VALUE (implicit or not) should be compiled.
591 ;; - :ALWAYS-HAS-TLS means that calls to SYMBOL-VALUE should access the TLS
592 ;; with a fixed offset. The index is assigned no later than load-time of
593 ;; the file containing code thus compiled. Presence of an index in the
594 ;; image that performed compilation is irrelevant (for now).
595 ;; - :ALWAYS-THREAD-LOCAL implies a fixed offset, *and* that the check for
596 ;; no-tls-value may be elided. There is currently no way to set this.
597 ;; Note that this does not affect elision of the check for unbound-marker
598 ;; which is under control of the :ALWAYS-BOUND info.
599 ;; - an integer is a permanent index, and also implies :ALWAYS-THREAD-LOCAL.
600 ;; Specials in the CL package (notably reader/printer controls) use a wired-tls,
601 ;; whether or not we bind per-thread [if we don't, that's a bug!]
602 ;; We don't assume wired TLS more generally, because user code often defines
603 ;; thousands of DEFVARs, possibly due to poor style, or due to ANSI's stance
604 ;; that DEFCONSTANT is only for EQL-comparable objects. In such cases with
605 ;; more symbols than can be bound per-thread, the compiler won't exacerbate
606 ;; things by making the loader eagerly assign a TLS index to every symbol
607 ;; ever referenced by SYMBOL-VALUE or SET. Depletion should occur lazily.
609 (define-info-type (:variable
:wired-tls
)
610 :type-spec
(or (member nil
:always-has-tls
:always-thread-local
)
611 fixnum
) ; the actual index, for thread slots (to be done)
614 (declare (symbol symbol
))
615 (and (eq (info :variable
:kind symbol
) :special
)
617 (eq (symbol-package symbol
) *cl-package
*)
619 (flet ((external-in-package-p (pkg)
620 (and (string= (package-name (symbol-package symbol
)) pkg
)
621 (eq (nth-value 1 (find-symbol (string symbol
) pkg
))
623 ;; I'm not worried about random extra externals in some bizarro
624 ;; host lisp. TLS assignment has no bearing on semantics at all.
625 (or (external-in-package-p "COMMON-LISP")
626 (external-in-package-p "SB-XC")))
629 ;;;; ":TYPE" subsection - Data pertaining to globally known types.
631 ;;; the kind of type described. We return :INSTANCE for standard types
632 ;;; that are implemented as structures. For PCL classes, that have
633 ;;; only been compiled, but not loaded yet, we return
634 ;;; :FORTHCOMING-DEFCLASS-TYPE.
635 (define-info-type (:type
:kind
)
636 :type-spec
(member :primitive
:defined
:instance
637 :forthcoming-defclass-type nil
)
638 :validate-function
(lambda (name new-value
)
639 (declare (ignore new-value
)
641 (when (info :declaration
:recognized name
)
642 (error 'declaration-type-conflict-error
643 :format-arguments
(list name
)))))
645 ;;; the expander function for a defined type
646 (define-info-type (:type
:expander
) :type-spec
(or function null
))
648 (define-info-type (:type
:documentation
) :type-spec
(or string null
))
650 ;;; function that parses type specifiers into CTYPE structures
651 (define-info-type (:type
:translator
) :type-spec
(or function null
))
653 ;;; If true, then the type coresponding to this name. Note that if
654 ;;; this is a built-in class with a translation, then this is the
655 ;;; translation, not the class object. This info type keeps track of
656 ;;; various atomic types (NIL etc.) and also serves as a cache to
657 ;;; ensure that common standard types (atomic and otherwise) are only
659 (define-info-type (:type
:builtin
) :type-spec
(or ctype null
))
661 ;;; The classoid-cell for this type
662 (define-info-type (:type
:classoid-cell
) :type-spec t
)
664 ;;; layout for this type being used by the compiler
665 (define-info-type (:type
:compiler-layout
)
666 :type-spec
(or layout null
)
667 :default
(lambda (name)
668 (let ((class (find-classoid name nil
)))
669 (when class
(classoid-layout class
)))))
671 ;;; DEFTYPE lambda-list
672 (define-info-type (:type
:lambda-list
) :type-spec list
)
674 (define-info-type (:type
:source-location
) :type-spec t
)
676 ;;;; ":TYPED-STRUCTURE" subsection.
677 ;;;; Data pertaining to structures that used DEFSTRUCT's :TYPE option.
678 (define-info-type (:typed-structure
:info
) :type-spec t
)
679 (define-info-type (:typed-structure
:documentation
) :type-spec
(or string null
))
681 ;;;; ":DECLARATION" subsection - Data pertaining to user-defined declarations.
682 ;; CLTL2 offers an API to provide a list of known declarations, but it is
683 ;; inefficient to iterate over info environments to find all such declarations,
684 ;; and this is likely to be even slower when info is attached
685 ;; directly to symbols, as it would entail do-all-symbols or similar.
686 ;; Therefore maintain a list of recognized declarations. This list makes the
687 ;; globaldb storage of same redundant, but oh well.
688 (defglobal *recognized-declarations
* nil
)
689 (define-info-type (:declaration
:recognized
)
691 ;; There's no portable way to unproclaim that a symbol is a declaration,
692 ;; but at the low-level permit new-value to be NIL.
693 :validate-function
(lambda (name new-value
)
694 (declare (symbol name
)
697 (when (info :type
:kind name
)
698 (error 'declaration-type-conflict-error
699 :format-arguments
(list name
)))
700 (pushnew name
*recognized-declarations
*))
702 (setq *recognized-declarations
*
703 (delete name
*recognized-declarations
*))))))
705 (define-info-type (:declaration
:handler
) :type-spec
(or function null
))
707 ;;;; ":ALIEN-TYPE" subsection - Data pertaining to globally known alien-types.
708 (define-info-type (:alien-type
:kind
)
709 :type-spec
(member :primitive
:defined
:unknown
)
711 (define-info-type (:alien-type
:translator
) :type-spec
(or function null
))
712 (define-info-type (:alien-type
:definition
) :type-spec
(or alien-type null
))
713 (define-info-type (:alien-type
:struct
) :type-spec
(or alien-type null
))
714 (define-info-type (:alien-type
:union
) :type-spec
(or alien-type null
))
715 (define-info-type (:alien-type
:enum
) :type-spec
(or alien-type null
))
717 ;;;; ":SETF" subsection - Data pertaining to expansion of the omnipotent macro.
718 (define-info-type (:setf
:inverse
) :type-spec
(or symbol null
))
719 (define-info-type (:setf
:documentation
) :type-spec
(or string null
))
720 (define-info-type (:setf
:expander
) :type-spec
(or function null
))
722 ;;;; ":RANDOM-DOCUMENTATION" subsection.
723 ;;; This is used for storing miscellaneous documentation types. The
724 ;;; stuff is an alist translating documentation kinds to values.
725 (define-info-type (:random-documentation
:stuff
) :type-spec list
)
727 ;;;; ":SOURCE-LOCATION" subsection.
728 ;;; This is kind of the opposite of what I'd have thought more logical,
729 ;;; where each of the above subsections - also called "info classes" -
730 ;;; has one of its kinds of information being :SOURCE-LOCATION. And in fact
731 ;;; that *is* how :TYPE was handled. However, many global entities
732 ;;; store their source-location hanging off some other hook, avoiding the
733 ;;; globaldb entirely, such as functions using a #<code-component>.
734 ;;; So either way is basically a hodgepodge.
736 (define-info-type (:source-location
:variable
) :type-spec t
)
737 (define-info-type (:source-location
:constant
) :type-spec t
)
738 (define-info-type (:source-location
:typed-structure
) :type-spec t
)
739 (define-info-type (:source-location
:symbol-macro
) :type-spec t
)
741 #!-sb-fluid
(declaim (freeze-type basic-info-env
))
743 ;; This is for the SB-INTROSPECT contrib module, and debugging.
744 (defun call-with-each-info (function symbol
)
745 (awhen (symbol-info-vector symbol
)
746 (%call-with-each-info function it symbol
)))
748 ;; This is for debugging at the REPL.
749 (defun show-info (sym)
752 (lambda (name type-num val
)
753 (unless (eq name prev
)
754 (format t
"~&~S" (setq prev name
)))
755 (let ((type (svref *info-types
* type-num
)))
756 (format t
"~& ~@[type ~D~]~@[~{~S ~S~}~] ~S = "
757 (if (not type
) type-num
)
759 (list (type-info-class type
) (type-info-name type
)))
761 (write val
:level
1)))
765 ;;; Now that we have finished initializing
766 ;;; *INFO-TYPES* (at compile time), generate code to set them at cold
767 ;;; load time to the same state they have currently.
769 (/show0
"beginning *INFO-TYPES* initialization")
771 ;; Host already has this array, do not clobber it
772 (setq *info-types
* (make-array (ash 1 type-number-bits
) :initial-element nil
))
774 (register-info-metadata (first x
) (second x
) (third x
) (fourth x
)))
775 '#.
(loop for info-type across
*info-types
*
777 collect
(list (type-info-number info-type
)
778 (type-info-class info-type
)
779 (type-info-name info-type
)
780 ;; KLUDGE: for repeatable xc fasls, to
781 ;; avoid different cross-compiler
782 ;; treatment of equal constants here we
783 ;; COPY-TREE, which is not in general a
784 ;; valid identity transformation
785 ;; [e.g. on (EQL (FOO))] but is OK for
786 ;; all the types we use here.
787 (copy-tree (type-info-type-spec info-type
)))))
788 (/show0
"done with *INFO-TYPES* initialization"))
790 ;;; At cold load time, after the INFO-TYPE objects have been created,
791 ;;; we can set their DEFAULT and TYPE slots.
794 ;; I [dpk] really think reversal now is a red herring.
795 ;; I see nothing that would fail here regardless of order.
796 ,@(reverse *!reversed-type-info-init-forms
*))))
799 ;;; Source transforms / compiler macros for INFO functions.
801 ;;; When building the XC, we give it a source transform, so that it can
802 ;;; compile INFO calls in the target efficiently; we also give it a compiler
803 ;;; macro, so that at least those INFO calls compiled after this file can be
804 ;;; efficient. (Host compiler-macros do not fire when compiling the target,
805 ;;; and source transforms don't fire when building the XC, so we need both.)
807 ;;; Target needs just one, since there compiler macros and source-transforms
809 (macrolet ((def (name lambda-list form
)
810 (aver (member 'class lambda-list
))
811 (aver (member 'type lambda-list
))
814 (define-source-transform ,name
,lambda-list
815 (if (and (keywordp class
) (keywordp type
))
818 (define-compiler-macro ,name
,(append '(&whole .whole.
) lambda-list
)
819 (if (and (keywordp class
) (keywordp type
))
823 (def info
(class type name
)
824 (let (#+sb-xc-host
(sb!xc
:*gensym-counter
* sb
!xc
:*gensym-counter
*)
825 (info (type-info-or-lose class type
)))
826 (with-unique-names (value foundp
)
827 `(multiple-value-bind (,value
,foundp
)
828 (get-info-value ,name
,(type-info-number info
))
829 (values (truly-the ,(type-info-type-spec info
) ,value
) ,foundp
)))))
831 (def (setf info
) (new-value class type name
)
832 (let* (#+sb-xc-host
(sb!xc
:*gensym-counter
* sb
!xc
:*gensym-counter
*)
833 (info (type-info-or-lose class type
))
834 (tin (type-info-number info
))
835 (type-spec (type-info-type-spec info
))
837 (when (type-info-validate-function info
)
838 ;; is (or ... null), but non-null in host implies non-null
840 (type-info-validate-function
841 (truly-the type-info
(svref *info-types
* ,tin
)))))))
842 (with-unique-names (new)
843 `(let ((,new
,new-value
))
844 ;; enforce type-correctness regardless of enclosing policy
845 (let ((,new
(locally (declare (optimize (safety 3)))
846 (the ,type-spec
,new
))))
848 `((funcall ,check
,name
,new
)))
849 (set-info-value ,name
,tin
,new
))))))
851 (def clear-info
(class type name
)
852 (let ((info (type-info-or-lose class type
)))
853 `(clear-info-value ,name
,(type-info-number info
)))))
855 (!defun-from-collected-cold-init-forms
!globaldb-cold-init
)