1 ;;;; code to detect whether a package has changed
3 ;;;; This is really old code which was most useful when first
4 ;;;; bootstrapping SBCL when only CMU CL was available as an XC host.
5 ;;;; Its main purpose was to check that legacy code like DEFMACRO
6 ;;;; DOLIST and DEFUN IR1-OPTIMIZE-UNTIL-DONE was all correctly
7 ;;;; converted from code which mutated the XC host into code which
8 ;;;; built things for the target.
10 ;;;; These days, things like DEFUN IR1-OPTIMIZE-UNTIL-DONE can't very
11 ;;;; well be mutating the cross-compiler host because we can build
12 ;;;; successfully under OpenMCL, which shouldn't have the same
13 ;;;; packages or symbols. So we don't need to worry very much about
14 ;;;; modifying the XC host's private packages. However, it's still
15 ;;;; conceivable that something affecting the XC host's CL package
16 ;;;; (maybe DEFMACRO DOLIST?) could be written in such a way that it
17 ;;;; would silently compile under SBCL, CMU CL, and even OpenMCL, and
18 ;;;; still be fundamentally wrong. Since it'd be good to prevent such
19 ;;;; modifications of the XC host's CL package, this code is still
20 ;;;; retained despite being a little strange.
22 ;;;; This software is part of the SBCL system. See the README file for
23 ;;;; more information.
25 ;;;; This software is derived from the CMU CL system, which was
26 ;;;; written at Carnegie Mellon University and released into the
27 ;;;; public domain. The software is in the public domain and is
28 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
29 ;;;; files for more information.
31 (in-package "SB-COLD")
34 (hash-table (make-hash-table :test
'eq
)
38 ;;; Return a SNAPSHOT object representing the current state of the
39 ;;; package associated with PACKAGE-DESIGNATOR.
41 ;;; This could be made more sensitive, checking for more things, such as
42 ;;; type definitions and documentation strings.
43 (defun take-snapshot (package-designator)
44 (let ((package (find-package package-designator
))
45 (result (make-snapshot)))
47 (error "can't find package ~S" package-designator
))
48 (do-symbols (symbol package
)
49 (multiple-value-bind (symbol-ignore status
)
50 (find-symbol (symbol-name symbol
) package
)
51 (declare (ignore symbol-ignore
))
52 (let ((symbol-properties nil
))
56 ((:internal
:external
)
58 (push (cons :symbol-value
(symbol-value symbol
))
60 (when (fboundp symbol
)
61 (push (cons :symbol-function
(symbol-function symbol
))
63 (when (macro-function symbol
)
64 (push (cons :macro-function
(macro-function symbol
))
66 (when (special-operator-p symbol
)
67 (push :special-operator
69 (push status symbol-properties
)
70 (setf (gethash symbol
(snapshot-hash-table result
))
73 (compile 'take-snapshot
)
75 (defun snapshot-diff (x y
)
76 (let ((xh (snapshot-hash-table x
))
77 (yh (snapshot-hash-table y
))
80 (maphash (lambda (key avalue
)
81 (declare (ignore avalue
))
82 (multiple-value-bind (bvalue bvalue?
) (gethash key bh
)
83 (declare (ignore bvalue
))
90 (maphash (lambda (key xvalue
)
91 (multiple-value-bind (yvalue yvalue?
) (gethash key yh
)
93 (unless (equalp xvalue yvalue
)
94 (push (list key xvalue yvalue
)
98 (compile 'snapshot-diff
)
100 ;;;; symbols in package COMMON-LISP which change regularly in the course of
101 ;;;; execution even if we don't mess with them, so that reporting changes
102 ;;;; would be more confusing than useful
105 (let ((result (make-hash-table :test
'eq
)))
106 (dolist (symbol `(;; These change regularly:
112 ;; These are bound when compiling and/or loading:
114 *compile-file-truename
*
115 *compile-file-pathname
*
118 ;; These change because CMU CL uses them as internal
122 #+cmu
(cl::*gc-trigger
*
124 cl
::*internal-symbol-output-function
*
128 cl
::read-buffer-length
129 cl
::*string-output-streams
*
130 cl
::*available-buffers
*
131 cl
::*current-unwind-protect-block
*
133 cl
::*free-fop-tables
*
134 cl
::*load-symbol-buffer
*
135 cl
::*load-symbol-buffer-size
*
138 ;; These two are changed by PURIFY.
139 cl
::*static-space-free-pointer
*
140 cl
::*static-space-end-pointer
*)
142 (setf (gethash symbol result
) t
))
145 ;;; specialized version of SNAPSHOT-DIFF to check on the COMMON-LISP package,
146 ;;; throwing away reports of differences in variables which are known to change
149 ;;; Note: The warnings from this code were somewhat useful when first setting
150 ;;; up the cross-compilation system, have a rather low signal/noise ratio in
151 ;;; the mature system. They can generally be safely ignored.
154 (defun cl-snapshot-diff (cl-snapshot)
155 (remove-if (lambda (entry)
156 (gethash (first entry
) *cl-ignorable-diffs
*))
157 (snapshot-diff cl-snapshot
(take-snapshot :common-lisp
))))
158 (defun warn-when-cl-snapshot-diff (cl-snapshot)
159 (let ((cl-snapshot-diff (cl-snapshot-diff cl-snapshot
)))
160 (when cl-snapshot-diff
161 (let ((*print-length
* 30)
163 (warn "CL snapshot differs:")
164 (print cl-snapshot-diff
*error-output
*)))))
165 (compile 'cl-snapshot-diff
)
166 (compile 'warn-when-cl-snapshot-diff
))