;; can get them from the table rather than dumping them again. The
;; EQUAL-TABLE is used for lists and strings, and the EQ-TABLE is
;; used for everything else. We use a separate EQ table to avoid
- ;; performance patholigies with objects for which EQUAL degnerates
+ ;; performance pathologies with objects for which EQUAL degenerates
;; to EQL. Everything entered in the EQUAL table is also entered in
;; the EQ table.
(equal-table (make-hash-table :test 'equal) :type hash-table)
;; an alist (PACKAGE . OFFSET) of the table offsets for each package
;; we have currently located.
(packages () :type list)
- ;; a table mapping from the Entry-Info structures for dumped XEPs to
+ ;; a table mapping from the ENTRY-INFO structures for dumped XEPs to
;; the table offsets of the corresponding code pointers
(entry-table (make-hash-table :test 'eq) :type hash-table)
;; a table holding back-patching info for forward references to XEPs.
- ;; The key is the Entry-Info structure for the XEP, and the value is
+ ;; The key is the ENTRY-INFO structure for the XEP, and the value is
;; a list of conses (<code-handle> . <offset>), where <code-handle>
;; is the offset in the table of the code object needing to be
;; patched, and <offset> is the offset that must be patched.
enclosing-object)
;;; a list of the CIRCULARITY structures for all of the circularities
-;;; detected in the current top-level call to DUMP-OBJECT. Setting
+;;; detected in the current top level call to DUMP-OBJECT. Setting
;;; this lobotomizes circularity detection as well, since circular
;;; dumping uses the table.
(defvar *circularities-detected*)
(declare (type (unsigned-byte 8) b) (type fasl-output fasl-output))
(write-byte b (fasl-output-stream fasl-output)))
-;;; Dump a 4 byte unsigned integer.
-(defun dump-unsigned-32 (num fasl-output)
- (declare (type (unsigned-byte 32) num))
+;; Dump a word-sized integer.
+(defun dump-word (num fasl-output)
+ (declare (type sb!vm:word num))
(declare (type fasl-output fasl-output))
(let ((stream (fasl-output-stream fasl-output)))
- (dotimes (i 4)
+ (dotimes (i sb!vm:n-word-bytes)
(write-byte (ldb (byte 8 (* 8 i)) num) stream))))
;;; Dump NUM to the fasl stream, represented by N bytes. This works
#!+sb-show
(when *fop-nop4-count*
(dump-byte ,(get 'fop-nop4 'fop-code) ,file)
- (dump-unsigned-32 (mod (incf *fop-nop4-count*) (expt 2 32)) ,file))
+ (dump-integer-as-n-bytes (mod (incf *fop-nop4-count*) (expt 2 32))
+ 4 ,file))
(dump-byte ',val ,file))
(error "compiler bug: ~S is not a legal fasload operator." fs))))
-;;; Dump a FOP-Code along with an integer argument, choosing the FOP
+;;; Dump a FOP-CODE along with an integer argument, choosing the FOP
;;; based on whether the argument will fit in a single byte.
;;;
;;; FIXME: This, like DUMP-FOP, should be a function with a
(dump-byte ,n-n ,n-file))
(t
(dump-fop ',word-fop ,n-file)
- (dump-unsigned-32 ,n-n ,n-file)))))
+ (dump-word ,n-n ,n-file)))))
;;; Push the object at table offset Handle on the fasl stack.
(defun dump-push (handle fasl-output)
(declare (type fasl-output fasl-output))
(unless *cold-load-dump*
(let ((handle (gethash x (fasl-output-equal-table fasl-output))))
- (cond (handle
- (dump-push handle fasl-output)
- t)
- (t
- nil)))))
+ (cond
+ (handle (dump-push handle fasl-output) t)
+ (t nil)))))
+(defun string-check-table (x fasl-output)
+ (declare (type fasl-output fasl-output)
+ (type string x))
+ (unless *cold-load-dump*
+ (let ((handle (cdr (assoc
+ (array-element-type x)
+ (gethash x (fasl-output-equal-table fasl-output))))))
+ (cond
+ (handle (dump-push handle fasl-output) t)
+ (t nil)))))
;;; These functions are called after dumping an object to save the
;;; object in the table. The object (also passed in as X) must already
(setf (gethash x (fasl-output-eq-table fasl-output)) handle)
(dump-push handle fasl-output)))
(values))
-
+(defun string-save-object (x fasl-output)
+ (declare (type fasl-output fasl-output)
+ (type string x))
+ (unless *cold-load-dump*
+ (let ((handle (dump-pop fasl-output)))
+ (push (cons (array-element-type x) handle)
+ (gethash x (fasl-output-equal-table fasl-output)))
+ (setf (gethash x (fasl-output-eq-table fasl-output)) handle)
+ (dump-push handle fasl-output)))
+ (values))
;;; Record X in File's CIRCULARITY-TABLE unless *COLD-LOAD-DUMP* is
;;; true. This is called on objects that we are about to dump might
;;; have a circular path through them.
\f
;;;; opening and closing fasl files
+;;; A utility function to write strings to (unsigned-byte 8) streams.
+;;; We restrict this to ASCII (with the averrance) because of
+;;; ambiguity of higher bytes: Unicode, some ISO-8859-x, or what? This
+;;; could be revisited in the event of doing funky things with stream
+;;; encodings -- CSR, 2002-04-25
+(defun fasl-write-string (string stream)
+ (loop for char across string
+ do (let ((code (char-code char)))
+ (aver (<= 0 code 127))
+ (write-byte code stream))))
+
;;; Open a fasl file, write its header, and return a FASL-OUTPUT
;;; object for dumping to it. Some human-readable information about
-;;; the source code is given by the string WHERE. If BYTE-P is true,
-;;; this file will contain no native code, and is thus largely
-;;; implementation independent.
+;;; the source code is given by the string WHERE.
(defun open-fasl-output (name where)
(declare (type pathname name))
(let* ((stream (open name
:direction :output
- :if-exists :new-version
+ :if-exists :supersede
:element-type 'sb!assem:assembly-unit))
(res (make-fasl-output :stream stream)))
;; Begin the header with the constant machine-readable (and
;; semi-human-readable) string which is used to identify fasl files.
- (write-string *fasl-header-string-start-string* stream)
+ (fasl-write-string *fasl-header-string-start-string* stream)
;; The constant string which begins the header is followed by
;; arbitrary human-readable text, terminated by a special
;; character code.
- (with-standard-io-syntax
- (format stream
- "~% ~
- compiled from ~S~% ~
- at ~A~% ~
- on ~A~% ~
- using ~A version ~A~%"
- where
- (format-universal-time nil (get-universal-time))
- (machine-instance)
- (sb!xc:lisp-implementation-type)
- (sb!xc:lisp-implementation-version)))
+ (fasl-write-string
+ (with-standard-io-syntax
+ (let ((*print-readably* nil)
+ (*print-pretty* nil))
+ (format nil
+ "~% ~
+ compiled from ~S~% ~
+ at ~A~% ~
+ on ~A~% ~
+ using ~A version ~A~%"
+ where
+ (format-universal-time nil (get-universal-time))
+ (machine-instance)
+ (sb!xc:lisp-implementation-type)
+ (sb!xc:lisp-implementation-version))))
+ stream)
(dump-byte +fasl-header-string-stop-char-code+ res)
- ;; Finish the header by outputting fasl file implementation and
- ;; version in machine-readable form.
- (let ((implementation +backend-fasl-file-implementation+))
- (dump-unsigned-32 (length (symbol-name implementation)) res)
- (dotimes (i (length (symbol-name implementation)))
- (dump-byte (char-code (aref (symbol-name implementation) i)) res)))
- (dump-unsigned-32 +fasl-file-version+ res)
+ ;; Finish the header by outputting fasl file implementation,
+ ;; version, and key *FEATURES*.
+ (flet ((dump-counted-string (string)
+ (dump-word (length string) res)
+ (dotimes (i (length string))
+ (dump-byte (char-code (aref string i)) res))))
+ (dump-counted-string (symbol-name +backend-fasl-file-implementation+))
+ (dump-word +fasl-file-version+ res)
+ (dump-counted-string *features-affecting-fasl-format*))
res))
;; End the group.
(dump-fop 'fop-verify-empty-stack fasl-output)
(dump-fop 'fop-verify-table-size fasl-output)
- (dump-unsigned-32 (fasl-output-table-free fasl-output)
+ (dump-word (fasl-output-table-free fasl-output)
fasl-output)
(dump-fop 'fop-end-group fasl-output)
;; take a little more care while dumping these.
;; So if better list coalescing is needed, start here.
;; -- WHN 2000-11-07
- (if (circular-list-p x)
+ (if (cyclic-list-p x)
(progn
(dump-list x file)
(eq-save-object x file))
(dump-structure x file)
(eq-save-object x file))
(array
- ;; FIXME: The comment at the head of
- ;; DUMP-NON-IMMEDIATE-OBJECT says it's for objects which
- ;; we want to save, instead of repeatedly dumping them.
- ;; But then we dump arrays here without doing anything
- ;; like EQUAL-SAVE-OBJECT. What gives?
+ ;; DUMP-ARRAY (and its callees) are responsible for
+ ;; updating the EQ and EQUAL hash tables.
(dump-array x file))
(number
(unless (equal-check-table x file)
;;; Dump an object of any type by dispatching to the correct
;;; type-specific dumping function. We pick off immediate objects,
-;;; symbols and and magic lists here. Other objects are handled by
+;;; symbols and magic lists here. Other objects are handled by
;;; DUMP-NON-IMMEDIATE-OBJECT.
;;;
;;; This is the function used for recursive calls to the fasl dumper.
;;; We don't worry about creating circularities here, since it is
-;;; assumed that there is a top-level call to DUMP-OBJECT.
+;;; assumed that there is a top level call to DUMP-OBJECT.
(defun sub-dump-object (x file)
(cond ((listp x)
(if x
(i 0 (1+ i)))
((eq current value)
(dump-fop 'fop-nthcdr file)
- (dump-unsigned-32 i file))
+ (dump-word i file))
(declare (type index i)))))
(ecase (circularity-type info)
(:rplacd (dump-fop 'fop-rplacd file))
(:svset (dump-fop 'fop-svset file))
(:struct-set (dump-fop 'fop-structset file)))
- (dump-unsigned-32 (gethash (circularity-object info) table) file)
- (dump-unsigned-32 (circularity-index info) file))))
+ (dump-word (gethash (circularity-object info) table) file)
+ (dump-word (circularity-index info) file))))
;;; Set up stuff for circularity detection, then dump an object. All
;;; shared and circular structure will be exactly preserved within a
;;; We peek at the object type so that we only pay the circular
;;; detection overhead on types of objects that might be circular.
(defun dump-object (x file)
- (if (or (array-header-p x)
- (simple-vector-p x)
- (consp x)
- (typep x 'instance))
+ (if (compound-object-p x)
(let ((*circularities-detected* ())
(circ (fasl-output-circularity-table file)))
(clrhash circ)
\f
;;;; number dumping
-;;; Dump a ratio.
(defun dump-ratio (x file)
(sub-dump-object (numerator x) file)
(sub-dump-object (denominator x) file)
(dump-fop 'fop-ratio file))
-;;; Dump an integer.
(defun dump-integer (n file)
(typecase n
((signed-byte 8)
(dump-fop 'fop-byte-integer file)
(dump-byte (logand #xFF n) file))
- ((unsigned-byte 31)
+ ((unsigned-byte #.(1- sb!vm:n-word-bits))
(dump-fop 'fop-word-integer file)
- (dump-unsigned-32 n file))
- ((signed-byte 32)
+ (dump-word n file))
+ ((signed-byte #.sb!vm:n-word-bits)
(dump-fop 'fop-word-integer file)
- (dump-integer-as-n-bytes n 4 file))
+ (dump-integer-as-n-bytes n #.sb!vm:n-word-bytes file))
(t
(let ((bytes (ceiling (1+ (integer-length n)) 8)))
(dump-fop* bytes fop-small-integer fop-integer file)
(dump-fop 'fop-double-float file)
(let ((x x))
(declare (double-float x))
- ;; FIXME: Why sometimes DUMP-UNSIGNED-32 and sometimes
- ;; DUMP-INTEGER-AS-N-BYTES .. 4?
- (dump-unsigned-32 (double-float-low-bits x) file)
+ (dump-integer-as-n-bytes (double-float-low-bits x) 4 file)
(dump-integer-as-n-bytes (double-float-high-bits x) 4 file)))
#!+long-float
(long-float
(dump-fop 'fop-complex-double-float file)
(let ((re (realpart x)))
(declare (double-float re))
- (dump-unsigned-32 (double-float-low-bits re) file)
+ (dump-integer-as-n-bytes (double-float-low-bits re) 4 file)
(dump-integer-as-n-bytes (double-float-high-bits re) 4 file))
(let ((im (imagpart x)))
(declare (double-float im))
- (dump-unsigned-32 (double-float-low-bits im) file)
+ (dump-integer-as-n-bytes (double-float-low-bits im) 4 file)
(dump-integer-as-n-bytes (double-float-high-bits im) 4 file)))
#!+long-float
((complex long-float)
;;; this function is not parallel to other functions DUMP-FOO, e.g.
;;; DUMP-SYMBOL and DUMP-LIST. The mapping between names and behavior
;;; should be made more consistent.
+(declaim (ftype (function (package fasl-output) index) dump-package))
(defun dump-package (pkg file)
- (declare (type package pkg) (type fasl-output file))
- (declare (values index))
(declare (inline assoc))
(cond ((cdr (assoc pkg (fasl-output-packages file) :test #'eq)))
(t
(unless *cold-load-dump*
(dump-fop 'fop-normal-load file))
- (dump-simple-string (package-name pkg) file)
+ #+sb-xc-host
+ (dump-simple-base-string
+ (coerce (package-name pkg) 'simple-base-string)
+ file)
+ #-sb-xc-host
+ (#!+sb-unicode dump-simple-character-string
+ #!-sb-unicode dump-simple-base-string
+ (coerce (package-name pkg) '(simple-array character (*)))
+ file)
(dump-fop 'fop-package file)
(unless *cold-load-dump*
(dump-fop 'fop-maybe-cold-load file))
(6 (dump-fop 'fop-list*-6 file))
(7 (dump-fop 'fop-list*-7 file))
(8 (dump-fop 'fop-list*-8 file))
- (T (do ((nn n (- nn 255)))
+ (t (do ((nn n (- nn 255)))
((< nn 256)
(dump-fop 'fop-list* file)
(dump-byte nn file))
(6 (dump-fop 'fop-list-6 file))
(7 (dump-fop 'fop-list-7 file))
(8 (dump-fop 'fop-list-8 file))
- (T (cond ((< n 256)
+ (t (cond ((< n 256)
(dump-fop 'fop-list file)
(dump-byte n file))
(t (dump-fop 'fop-list file)
;;; tables.
(defun dump-vector (x file)
(let ((simple-version (if (array-header-p x)
- (coerce x 'simple-array)
+ (coerce x `(simple-array
+ ,(array-element-type x)
+ (*)))
x)))
(typecase simple-version
+ #+sb-xc-host
+ (simple-string
+ (unless (string-check-table x file)
+ (dump-simple-base-string simple-version file)
+ (string-save-object x file)))
+ #-sb-xc-host
(simple-base-string
- (unless (equal-check-table x file)
- (dump-simple-string simple-version file)
- (equal-save-object x file)))
+ (unless (string-check-table x file)
+ (dump-simple-base-string simple-version file)
+ (string-save-object x file)))
+ #-sb-xc-host
+ ((simple-array character (*))
+ #!+sb-unicode
+ (unless (string-check-table x file)
+ (dump-simple-character-string simple-version file)
+ (string-save-object x file))
+ #!-sb-unicode
+ (bug "how did we get here?"))
(simple-vector
(dump-simple-vector simple-version file)
(eq-save-object x file))
(t
(sub-dump-object obj file))))))
+;;; In the grand scheme of things I don't pretend to understand any
+;;; more how this works, or indeed whether. But to write out specialized
+;;; vectors in the same format as fop-int-vector expects to read them
+;;; we need to be target-endian. dump-integer-as-n-bytes always writes
+;;; little-endian (which is correct for all other integers) so for a bigendian
+;;; target we need to swap octets -- CSR, after DB
+
+(defun octet-swap (word bits)
+ "BITS must be a multiple of 8"
+ (do ((input word (ash input -8))
+ (output 0 (logior (ash output 8) (logand input #xff)))
+ (bits bits (- bits 8)))
+ ((<= bits 0) output)))
+
(defun dump-i-vector (vec file &key data-only)
(declare (type (simple-array * (*)) vec))
(let ((len (length vec)))
(labels ((dump-unsigned-vector (size bytes)
(unless data-only
(dump-fop 'fop-int-vector file)
- (dump-unsigned-32 len file)
+ (dump-word len file)
(dump-byte size file))
;; The case which is easy to handle in a portable way is when
;; the element size is a multiple of the output byte size, and
;; (SIMPLE-ARRAY (UNSIGNED-BYTE 8) *).) The other cases are only
;; needed in the target SBCL, so we let them be handled with
;; unportable bit bashing.
- (cond ((>= size 8) ; easy cases
+ (cond ((>= size 7) ; easy cases
(multiple-value-bind (floor rem) (floor size 8)
- (aver (zerop rem))
+ (aver (or (zerop rem) (= rem 7)))
+ (when (= rem 7)
+ (setq size (1+ size))
+ (setq floor (1+ floor)))
(dovector (i vec)
- (dump-integer-as-n-bytes i floor file))))
+ (dump-integer-as-n-bytes
+ (ecase sb!c:*backend-byte-order*
+ (:little-endian i)
+ (:big-endian (octet-swap i size)))
+ floor file))))
(t ; harder cases, not supported in cross-compiler
(dump-raw-bytes vec bytes file))))
(dump-signed-vector (size bytes)
;; target machine.)
(unless data-only
(dump-fop 'fop-signed-int-vector file)
- (dump-unsigned-32 len file)
+ (dump-word len file)
(dump-byte size file))
(dump-raw-bytes vec bytes file)))
(etypecase vec
- ;; KLUDGE: What exactly does the (ASH .. -3) stuff do? -- WHN 19990902
+ #-sb-xc-host
+ ((simple-array nil (*))
+ (dump-unsigned-vector 0 0))
(simple-bit-vector
- (dump-unsigned-vector 1 (ash (+ (the index len) 7) -3)))
+ (dump-unsigned-vector 1 (ceiling len 8))) ; bits to bytes
+ ;; KLUDGE: This isn't the best way of expressing that the host
+ ;; may not have specializations for (unsigned-byte 2) and
+ ;; (unsigned-byte 4), which means that these types are
+ ;; type-equivalent to (simple-array (unsigned-byte 8) (*));
+ ;; the workaround is to remove them from the etypecase, since
+ ;; they can't be dumped from the cross-compiler anyway. --
+ ;; CSR, 2002-05-07
+ #-sb-xc-host
((simple-array (unsigned-byte 2) (*))
- (dump-unsigned-vector 2 (ash (+ (the index (ash len 1)) 7) -3)))
+ (dump-unsigned-vector 2 (ceiling (ash len 1) 8))) ; bits to bytes
+ #-sb-xc-host
((simple-array (unsigned-byte 4) (*))
- (dump-unsigned-vector 4 (ash (+ (the index (ash len 2)) 7) -3)))
+ (dump-unsigned-vector 4 (ceiling (ash len 2) 8))) ; bits to bytes
+ #-sb-xc-host
+ ((simple-array (unsigned-byte 7) (*))
+ (dump-unsigned-vector 7 len))
((simple-array (unsigned-byte 8) (*))
(dump-unsigned-vector 8 len))
+ #-sb-xc-host
+ ((simple-array (unsigned-byte 15) (*))
+ (dump-unsigned-vector 15 (* 2 len)))
((simple-array (unsigned-byte 16) (*))
(dump-unsigned-vector 16 (* 2 len)))
+ #-sb-xc-host
+ ((simple-array (unsigned-byte 31) (*))
+ (dump-unsigned-vector 31 (* 4 len)))
((simple-array (unsigned-byte 32) (*))
(dump-unsigned-vector 32 (* 4 len)))
+ #-sb-xc-host
+ #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
+ ((simple-array (unsigned-byte 63) (*))
+ (dump-unsigned-vector 63 (* 8 len)))
+ #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
+ ((simple-array (unsigned-byte 64) (*))
+ (dump-unsigned-vector 64 (* 8 len)))
((simple-array (signed-byte 8) (*))
(dump-signed-vector 8 len))
((simple-array (signed-byte 16) (*))
(dump-signed-vector 16 (* 2 len)))
+ #!+#.(cl:if (cl:= 32 sb!vm:n-word-bits) '(and) '(or))
+ ((simple-array (unsigned-byte 29) (*))
+ (dump-signed-vector 29 (* 4 len)))
+ #!+#.(cl:if (cl:= 32 sb!vm:n-word-bits) '(and) '(or))
((simple-array (signed-byte 30) (*))
(dump-signed-vector 30 (* 4 len)))
((simple-array (signed-byte 32) (*))
- (dump-signed-vector 32 (* 4 len)))))))
+ (dump-signed-vector 32 (* 4 len)))
+ #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
+ ((simple-array (unsigned-byte 60) (*))
+ (dump-signed-vector 60 (* 8 len)))
+ #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
+ ((simple-array (signed-byte 61) (*))
+ (dump-signed-vector 61 (* 8 len)))
+ #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
+ ((simple-array (signed-byte 64) (*))
+ (dump-signed-vector 64 (* 8 len)))))))
\f
;;; Dump characters and string-ish things.
-(defun dump-character (ch file)
+(defun dump-character (char file)
+ (let ((code (sb!xc:char-code char)))
+ (cond
+ ((< code 256)
(dump-fop 'fop-short-character file)
- (dump-byte (char-code ch) file))
+ (dump-byte code file))
+ (t
+ (dump-fop 'fop-character file)
+ (dump-word code file)))))
-;;; a helper function shared by DUMP-SIMPLE-STRING and DUMP-SYMBOL
-(defun dump-characters-of-string (s fasl-output)
- (declare (type string s) (type fasl-output fasl-output))
+(defun dump-base-chars-of-string (s fasl-output)
+ (declare #+sb-xc-host (type simple-string s)
+ #-sb-xc-host (type simple-base-string s)
+ (type fasl-output fasl-output))
(dovector (c s)
- (dump-byte (char-code c) fasl-output))
+ (dump-byte (sb!xc:char-code c) fasl-output))
(values))
+
;;; Dump a SIMPLE-BASE-STRING.
-;;; FIXME: should be called DUMP-SIMPLE-BASE-STRING then
-(defun dump-simple-string (s file)
- (declare (type simple-base-string s))
- (dump-fop* (length s) fop-small-string fop-string file)
- (dump-characters-of-string s file)
+(defun dump-simple-base-string (s file)
+ #+sb-xc-host (declare (type simple-string s))
+ #-sb-xc-host (declare (type simple-base-string s))
+ (dump-fop* (length s) fop-small-base-string fop-base-string file)
+ (dump-base-chars-of-string s file)
(values))
;;; If we get here, it is assumed that the symbol isn't in the table,
fop-symbol-in-byte-package-save
fop-symbol-in-package-save
file)
- (dump-unsigned-32 pname-length file)))
+ (dump-word pname-length file)))
- (dump-characters-of-string pname file)
+ #+sb-xc-host (dump-base-chars-of-string pname file)
+ #-sb-xc-host (#!+sb-unicode dump-characters-of-string
+ #!-sb-unicode dump-base-chars-of-string
+ pname file)
(unless *cold-load-dump*
(setf (gethash s (fasl-output-eq-table file))
(declare (type sb!assem:segment segment)
(type fasl-output fasl-output))
(let* ((stream (fasl-output-stream fasl-output))
- (nwritten (write-segment-contents segment stream)))
+ (n-written (write-segment-contents segment stream)))
;; In CMU CL there was no enforced connection between the CODE-LENGTH
;; argument and the number of bytes actually written. I added this
;; assertion while trying to debug portable genesis. -- WHN 19990902
- (unless (= code-length nwritten)
- (error "internal error, code-length=~D, nwritten=~D"
- code-length
- nwritten)))
+ (unless (= code-length n-written)
+ (bug "code-length=~W, n-written=~W" code-length n-written)))
(values))
;;; Dump all the fixups. Currently there are three flavors of fixup:
;;; - code object references: don't need a name.
(defun dump-fixups (fixups fasl-output)
(declare (list fixups) (type fasl-output fasl-output))
- (dolist (info fixups)
- ;; FIXME: Packing data with LIST in NOTE-FIXUP and unpacking them
- ;; with FIRST, SECOND, and THIRD here is hard to follow and
- ;; maintain. Perhaps we could define a FIXUP-INFO structure to use
- ;; instead, and rename *FIXUPS* to *FIXUP-INFO-LIST*?
- (let* ((kind (first info))
- (fixup (second info))
+ (dolist (note fixups)
+ (let* ((kind (fixup-note-kind note))
+ (fixup (fixup-note-fixup note))
+ (position (fixup-note-position note))
(name (fixup-name fixup))
- (flavor (fixup-flavor fixup))
- (offset (third info)))
- ;; FIXME: This OFFSET is not what's called OFFSET in the FIXUP
- ;; structure, it's what's called POSN in NOTE-FIXUP. (As far as
- ;; I can tell, FIXUP-OFFSET is not actually an offset, it's an
- ;; internal label used instead of NAME for :CODE-OBJECT fixups.
- ;; Notice that in the :CODE-OBJECT case, NAME is ignored.)
+ (flavor (fixup-flavor fixup)))
(dump-fop 'fop-normal-load fasl-output)
(let ((*cold-load-dump* t))
(dump-object kind fasl-output))
(dump-fop 'fop-maybe-cold-load fasl-output)
;; Depending on the flavor, we may have various kinds of
- ;; noise before the offset.
+ ;; noise before the position.
(ecase flavor
(:assembly-routine
(aver (symbolp name))
(dump-object name fasl-output))
(dump-fop 'fop-maybe-cold-load fasl-output)
(dump-fop 'fop-assembler-fixup fasl-output))
- (:foreign
+ ((:foreign :foreign-dataref)
(aver (stringp name))
- (dump-fop 'fop-foreign-fixup fasl-output)
+ (ecase flavor
+ (:foreign
+ (dump-fop 'fop-foreign-fixup fasl-output))
+ #!+linkage-table
+ (:foreign-dataref
+ (dump-fop 'fop-foreign-dataref-fixup fasl-output)))
(let ((len (length name)))
(aver (< len 256)) ; (limit imposed by fop definition)
(dump-byte len fasl-output)
(:code-object
(aver (null name))
(dump-fop 'fop-code-object-fixup fasl-output)))
- ;; No matter what the flavor, we'll always dump the offset.
- (dump-unsigned-32 offset fasl-output)))
+ ;; No matter what the flavor, we'll always dump the position
+ (dump-word position fasl-output)))
(values))
;;; Dump out the constant pool and code-vector for component, push the
;; hardwired to be empty. And SBCL doesn't have GENGC (and as
;; far as I know no modern CMU CL does either -- WHN
;; 2001-10-05). So might we be able to get rid of trace tables?
+ ;;
+ ;; Note that gencgc also does something with the trace table.
- ;; Dump the constants, noting any :entries that have to be fixed up.
- (do ((i sb!vm:code-constants-offset (1+ i)))
- ((>= i header-length))
+ ;; Dump the constants, noting any :ENTRY constants that have to
+ ;; be patched.
+ (loop for i from sb!vm:code-constants-offset below header-length do
(let ((entry (aref constants i)))
(etypecase entry
(constant
(handle (gethash info
(fasl-output-entry-table
fasl-output))))
+ (declare (type sb!c::entry-info info))
(cond
(handle
(dump-push handle fasl-output))
(cond ((and (< num-consts #x100) (< total-length #x10000))
(dump-fop 'fop-small-code fasl-output)
(dump-byte num-consts fasl-output)
- (dump-integer-as-n-bytes total-length 2 fasl-output))
+ (dump-integer-as-n-bytes total-length (/ sb!vm:n-word-bytes 2) fasl-output))
(t
(dump-fop 'fop-code fasl-output)
- (dump-unsigned-32 num-consts fasl-output)
- (dump-unsigned-32 total-length fasl-output))))
+ (dump-word num-consts fasl-output)
+ (dump-word total-length fasl-output))))
;; These two dumps are only ones which contribute to our
;; TOTAL-LENGTH value.
(dump-fixups fixups fasl-output)
(dump-fop 'fop-sanctify-for-execution fasl-output)
+
(let ((handle (dump-pop fasl-output)))
(dolist (patch (patches))
(push (cons handle (cdr patch))
(defun dump-assembler-routines (code-segment length fixups routines file)
(dump-fop 'fop-assembler-code file)
- (dump-unsigned-32 length file)
+ (dump-word length file)
(write-segment-contents code-segment (fasl-output-stream file))
(dolist (routine routines)
(dump-fop 'fop-normal-load file)
(dump-object (car routine) file))
(dump-fop 'fop-maybe-cold-load file)
(dump-fop 'fop-assembler-routine file)
- (dump-unsigned-32 (label-position (cdr routine)) file))
+ (dump-word (label-position (cdr routine)) file))
(dump-fixups fixups file)
(dump-fop 'fop-sanctify-for-execution file)
(dump-pop file))
-;;; Dump a function-entry data structure corresponding to ENTRY to
+;;; Dump a function entry data structure corresponding to ENTRY to
;;; FILE. CODE-HANDLE is the table offset of the code object for the
;;; component.
(defun dump-one-entry (entry code-handle file)
(dump-object name file)
(dump-object (sb!c::entry-info-arguments entry) file)
(dump-object (sb!c::entry-info-type entry) file)
- (dump-fop 'fop-function-entry file)
- (dump-unsigned-32 (label-position (sb!c::entry-info-offset entry)) file)
+ (dump-fop 'fop-fun-entry file)
+ (dump-word (label-position (sb!c::entry-info-offset entry)) file)
(dump-pop file)))
;;; Alter the code object referenced by CODE-HANDLE at the specified
(dump-fop 'fop-verify-empty-stack file)
(dump-fop 'fop-verify-table-size file)
- (dump-unsigned-32 (fasl-output-table-free file) file)
+ (dump-word (fasl-output-table-free file) file)
#!+sb-dyncount
(let ((info (sb!c::ir2-component-dyncount-info (component-info component))))
(dump-push handle fasl-output))
(values))
-;;; Dump a FOP-FUNCALL to call an already-dumped top-level lambda at
+;;; Dump a FOP-FUNCALL to call an already-dumped top level lambda at
;;; load time.
-(defun fasl-dump-top-level-lambda-call (fun fasl-output)
+(defun fasl-dump-toplevel-lambda-call (fun fasl-output)
(declare (type sb!c::clambda fun))
(dump-push-previously-dumped-fun fun fasl-output)
(dump-fop 'fop-funcall-for-effect fasl-output)
(dolist (info-handle (fasl-output-debug-info fasl-output))
(dump-push res-handle fasl-output)
(dump-fop 'fop-structset fasl-output)
- (dump-unsigned-32 info-handle fasl-output)
- (dump-unsigned-32 2 fasl-output))))
+ (dump-word info-handle fasl-output)
+ ;; FIXME: what is this bare `2'? --njf, 2004-08-16
+ (dump-word 2 fasl-output))))
(setf (fasl-output-debug-info fasl-output) nil)
(values))
\f
(error "attempt to dump invalid structure:~% ~S~%How did this happen?"
struct)))
(note-potential-circularity struct file)
- (do ((index 0 (1+ index))
- (length (%instance-length struct))
- (circ (fasl-output-circularity-table file)))
- ((= index length)
+ (aver (%instance-ref struct 0))
+ (do* ((length (%instance-length struct))
+ (ntagged (- length (layout-n-untagged-slots (%instance-ref struct 0))))
+ (circ (fasl-output-circularity-table file))
+ ;; last slot first on the stack, so that the layout is on top:
+ (index (1- length) (1- index)))
+ ((minusp index)
(dump-fop* length fop-small-struct fop-struct file))
- (let* ((obj (%instance-ref struct index))
+ (let* ((obj (if (>= index ntagged)
+ (%raw-instance-ref/word struct (- length index 1))
+ (%instance-ref struct index)))
(ref (gethash obj circ)))
(cond (ref
+ (aver (not (zerop index)))
(push (make-circularity :type :struct-set
:object struct
:index index
(defun dump-layout (obj file)
(when (layout-invalid obj)
(compiler-error "attempt to dump reference to obsolete class: ~S"
- (layout-class obj)))
- (let ((name (sb!xc:class-name (layout-class obj))))
+ (layout-classoid obj)))
+ (let ((name (classoid-name (layout-classoid obj))))
(unless name
(compiler-error "dumping anonymous layout: ~S" obj))
(dump-fop 'fop-normal-load file)
(sub-dump-object (layout-inherits obj) file)
(sub-dump-object (layout-depthoid obj) file)
(sub-dump-object (layout-length obj) file)
+ (sub-dump-object (layout-n-untagged-slots obj) file)
(dump-fop 'fop-layout file))