0.8.16.6:
[sbcl.git] / src / compiler / dump.lisp
index 4ca7e8f..83229a0 100644 (file)
@@ -33,7 +33,7 @@
   ;; 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)
   (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-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)
     ;; character code.
     (fasl-write-string
      (with-standard-io-syntax
-       (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)))
+       (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)
 
 
 ;;; 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.
               (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
     ((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)
     (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
                           (ecase sb!c:*backend-byte-order*
               ;; 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
        ;; 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.
 
                      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)
 
 ;;;  - 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 :ENTRY constants that have to
       ;; be patched.
        (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.
 
 (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-object (sb!c::entry-info-arguments entry) file)
     (dump-object (sb!c::entry-info-type entry) file)
     (dump-fop 'fop-fun-entry file)
-    (dump-unsigned-32 (label-position (sb!c::entry-info-offset 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))))
       (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
 (defun dump-layout (obj file)
   (when (layout-invalid obj)
     (compiler-error "attempt to dump reference to obsolete class: ~S"
-                   (layout-class obj)))
+                   (layout-classoid obj)))
   (let ((name (classoid-name (layout-classoid obj))))
     (unless name
       (compiler-error "dumping anonymous layout: ~S" obj))