;;;; for !COLD-INIT to be called at cold load time. !COLD-INIT is
;;;; responsible for explicitly initializing anything which has to be
;;;; initialized early before it transfers control to the ordinary
-;;;; top-level forms.
+;;;; top level forms.
;;;;
;;;; (In CMU CL, and in SBCL as of 0.6.9 anyway, functions not defined
;;;; by DEFUN aren't set up specially by GENESIS. In particular,
(defstruct (gspace (:constructor %make-gspace)
(:copier nil))
;; name and identifier for this GSPACE
- (name (required-argument) :type symbol :read-only t)
- (identifier (required-argument) :type fixnum :read-only t)
+ (name (missing-arg) :type symbol :read-only t)
+ (identifier (missing-arg) :type fixnum :read-only t)
;; the word address where the data will be loaded
- (word-address (required-argument) :type unsigned-byte :read-only t)
+ (word-address (missing-arg) :type unsigned-byte :read-only t)
;; the data themselves. (Note that in CMU CL this was a pair
;; of fields SAP and WORDS-ALLOCATED, but that wasn't very portable.)
(bytes (make-array target-space-alignment :element-type '(unsigned-byte 8))
(ash (descriptor-low des)
(- 1 sb!vm:n-lowtag-bits)))))
(format stream
- "for fixnum: ~D"
+ "for fixnum: ~W"
(if (> unsigned #x1FFFFFFF)
(- unsigned #x40000000)
unsigned))))
(defun make-fixnum-descriptor (num)
(when (>= (integer-length num)
(1+ (- sb!vm:n-word-bits sb!vm:n-lowtag-bits)))
- (error "~D is too big for a fixnum." num))
+ (error "~W is too big for a fixnum." num))
(make-random-descriptor (ash num (1- sb!vm:n-lowtag-bits))))
(defun make-other-immediate-descriptor (data type)
((> index words)
(unless (zerop (integer-length remainder))
;; FIXME: Shouldn't this be a fatal error?
- (warn "~D words of ~D were written, but ~D bits were left over."
+ (warn "~W words of ~W were written, but ~W bits were left over."
words n remainder)))
(let ((word (ldb (byte sb!vm:n-word-bits 0) remainder)))
(write-wordindexed handle index
(defun cold-intern (symbol &optional (package (symbol-package symbol)))
;; Anything on the cross-compilation host which refers to the target
- ;; machinery through the host SB-XC package can be translated to
+ ;; machinery through the host SB-XC package should be translated to
;; something on the target which refers to the same machinery
;; through the target COMMON-LISP package.
(let ((p (find-package "SB-XC")))
(when (eq (symbol-package symbol) p)
(setf symbol (intern (symbol-name symbol) *cl-package*))))
+ ;; Make sure that the symbol has an appropriate package. In
+ ;; particular, catch the so-easy-to-make error of typing something
+ ;; like SB-KERNEL:%BYTE-BLT in cold sources when what you really
+ ;; need is SB!KERNEL:%BYTE-BLT.
+ (let ((package-name (package-name package)))
+ (cond ((find package-name '("COMMON-LISP" "KEYWORD") :test #'string=)
+ ;; That's OK then.
+ (values))
+ ((string= package-name "SB!" :end1 3 :end2 3)
+ ;; That looks OK, too. (All the target-code packages
+ ;; have names like that.)
+ (values))
+ (t
+ ;; looks bad: maybe COMMON-LISP-USER? maybe an extension
+ ;; package in the xc host? something we can't think of
+ ;; a valid reason to dump, anyway...
+ (bug "internal error: PACKAGE-NAME=~S looks too much like a typo."
+ package-name))))
+
(let (;; Information about each cold-interned symbol is stored
;; in COLD-INTERN-INFO.
;; (CAR COLD-INTERN-INFO) = descriptor of symbol
(descriptor-low *nil-descriptor*))))
(unless (= offset-wanted offset-found)
;; FIXME: should be fatal
- (warn "Offset from ~S to ~S is ~D, not ~D"
+ (warn "Offset from ~S to ~S is ~W, not ~W"
symbol
nil
offset-found
;;; intern it.
(defun finish-symbols ()
- ;; FIXME: Why use SETQ (setting symbol value) instead of just using
- ;; the function values for these things?? I.e. why do we need this
- ;; section at all? Is it because all the FDEFINITION stuff gets in
- ;; the way of reading function values and is too hairy to rely on at
- ;; cold boot? FIXME: Most of these are in *STATIC-SYMBOLS* in
- ;; parms.lisp, but %HANDLE-FUN-END-BREAKPOINT is not. Why?
- ;; Explain.
+ ;; I think the point of setting these functions into SYMBOL-VALUEs
+ ;; here, instead of using SYMBOL-FUNCTION, is that in CMU CL
+ ;; SYMBOL-FUNCTION reduces to FDEFINITION, which is a pretty
+ ;; hairy operation (involving globaldb.lisp etc.) which we don't
+ ;; want to invoke early in cold init. -- WHN 2001-12-05
+ ;;
+ ;; FIXME: So OK, that's a reasonable reason to do something weird like
+ ;; this, but this is still a weird thing to do, and we should change
+ ;; the names to highlight that something weird is going on. Perhaps
+ ;; *MAYBE-GC-FUN*, *INTERNAL-ERROR-FUN*, *HANDLE-BREAKPOINT-FUN*,
+ ;; and *HANDLE-FUN-END-BREAKPOINT-FUN*...
(macrolet ((frob (symbol)
`(cold-set ',symbol
(cold-fdefinition-object (cold-intern ',symbol)))))
(cold-set '*current-catch-block* (make-fixnum-descriptor 0))
(cold-set '*current-unwind-protect-block* (make-fixnum-descriptor 0))
- (cold-set '*eval-stack-top* (make-fixnum-descriptor 0))
(cold-set '*free-interrupt-context-index* (make-fixnum-descriptor 0))
sb!vm:word-shift))))
(#.sb!vm:closure-header-widetag
(make-random-descriptor
- (cold-foreign-symbol-address-as-integer "closure_tramp")))))
+ (cold-foreign-symbol-address-as-integer
+ "closure_tramp")))))
fdefn))
(defun initialize-static-fns ()
(let ((*cold-fdefn-gspace* *static*))
- (dolist (sym sb!vm:*static-functions*)
+ (dolist (sym sb!vm:*static-funs*)
(let* ((fdefn (cold-fdefinition-object (cold-intern sym)))
(offset (- (+ (- (descriptor-low fdefn)
sb!vm:other-pointer-lowtag)
(* sb!vm:fdefn-raw-addr-slot sb!vm:n-word-bytes))
(descriptor-low *nil-descriptor*)))
- (desired (sb!vm:static-function-offset sym)))
+ (desired (sb!vm:static-fun-offset sym)))
(unless (= offset desired)
;; FIXME: should be fatal
- (warn "Offset from FDEFN ~S to ~S is ~D, not ~D."
+ (warn "Offset from FDEFN ~S to ~S is ~W, not ~W."
sym nil offset desired))))))
(defun list-all-fdefn-objects ()
(let ((result *nil-descriptor*))
- (maphash #'(lambda (key value)
- (declare (ignore key))
- (cold-push value result))
+ (maphash (lambda (key value)
+ (declare (ignore key))
+ (cold-push value result))
*cold-fdefn-objects*)
result))
\f
;;;; general machinery for cold-loading FASL files
;;; FOP functions for cold loading
-(defvar *cold-fop-functions*
- ;; We start out with a copy of the ordinary *FOP-FUNCTIONS*. The
- ;; ones which aren't appropriate for cold load will be destructively
+(defvar *cold-fop-funs*
+ ;; We start out with a copy of the ordinary *FOP-FUNS*. The ones
+ ;; which aren't appropriate for cold load will be destructively
;; modified.
- (copy-seq *fop-functions*))
+ (copy-seq *fop-funs*))
-(defvar *normal-fop-functions*)
+(defvar *normal-fop-funs*)
;;; Cause a fop to have a special definition for cold load.
;;;
;;; This is similar to DEFINE-FOP, but unlike DEFINE-FOP, this version
;;; (1) looks up the code for this name (created by a previous
;; DEFINE-FOP) instead of creating a code, and
-;;; (2) stores its definition in the *COLD-FOP-FUNCTIONS* vector,
-;;; instead of storing in the *FOP-FUNCTIONS* vector.
-(defmacro define-cold-fop ((name &optional (pushp t)) &rest forms)
- (aver (member pushp '(nil t :nope)))
+;;; (2) stores its definition in the *COLD-FOP-FUNS* vector,
+;;; instead of storing in the *FOP-FUNS* vector.
+(defmacro define-cold-fop ((name &key (pushp t) (stackp t)) &rest forms)
+ (aver (member pushp '(nil t)))
+ (aver (member stackp '(nil t)))
(let ((code (get name 'fop-code))
(fname (symbolicate "COLD-" name)))
(unless code
(error "~S is not a defined FOP." name))
`(progn
(defun ,fname ()
- ,@(if (eq pushp :nope)
- forms
- `((with-fop-stack ,pushp ,@forms))))
- (setf (svref *cold-fop-functions* ,code) #',fname))))
-
-(defmacro clone-cold-fop ((name &optional (pushp t)) (small-name) &rest forms)
- (aver (member pushp '(nil t :nope)))
+ ,@(if stackp
+ `((with-fop-stack ,pushp ,@forms))
+ forms))
+ (setf (svref *cold-fop-funs* ,code) #',fname))))
+
+(defmacro clone-cold-fop ((name &key (pushp t) (stackp t)) (small-name) &rest forms)
+ (aver (member pushp '(nil t)))
+ (aver (member stackp '(nil t)))
`(progn
(macrolet ((clone-arg () '(read-arg 4)))
- (define-cold-fop (,name ,pushp) ,@forms))
+ (define-cold-fop (,name :pushp ,pushp :stackp ,stackp) ,@forms))
(macrolet ((clone-arg () '(read-arg 1)))
- (define-cold-fop (,small-name ,pushp) ,@forms))))
+ (define-cold-fop (,small-name :pushp ,pushp :stackp ,stackp) ,@forms))))
;;; Cause a fop to be undefined in cold load.
(defmacro not-cold-fop (name)
(defun cold-load (filename)
#!+sb-doc
"Load the file named by FILENAME into the cold load image being built."
- (let* ((*normal-fop-functions* *fop-functions*)
- (*fop-functions* *cold-fop-functions*)
+ (let* ((*normal-fop-funs* *fop-funs*)
+ (*fop-funs* *cold-fop-funs*)
(*cold-load-filename* (etypecase filename
(string filename)
(pathname (namestring filename)))))
(define-cold-fop (fop-empty-list) *nil-descriptor*)
(define-cold-fop (fop-truth) (cold-intern t))
-(define-cold-fop (fop-normal-load :nope)
- (setq *fop-functions* *normal-fop-functions*))
+(define-cold-fop (fop-normal-load :stackp nil)
+ (setq *fop-funs* *normal-fop-funs*))
-(define-fop (fop-maybe-cold-load 82 :nope)
+(define-fop (fop-maybe-cold-load 82 :stackp nil)
(when *cold-load-filename*
- (setq *fop-functions* *cold-fop-functions*)))
+ (setq *fop-funs* *cold-fop-funs*)))
-(define-cold-fop (fop-maybe-cold-load :nope))
+(define-cold-fop (fop-maybe-cold-load :stackp nil))
(clone-cold-fop (fop-struct)
(fop-small-struct)
(8 sb!vm:simple-array-unsigned-byte-8-widetag)
(16 sb!vm:simple-array-unsigned-byte-16-widetag)
(32 sb!vm:simple-array-unsigned-byte-32-widetag)
- (t (error "losing element size: ~D" sizebits))))
+ (t (error "losing element size: ~W" sizebits))))
(result (allocate-vector-object *dynamic* sizebits len type))
(start (+ (descriptor-byte-offset result)
(ash sb!vm:vector-data-offset sb!vm:word-shift)))
;;;; cold fops for loading numbers
(defmacro define-cold-number-fop (fop)
- `(define-cold-fop (,fop :nope)
+ `(define-cold-fop (,fop :stackp nil)
;; Invoke the ordinary warm version of this fop to push the
;; number.
(,fop)
*load-time-value-counter*
sb!vm:simple-vector-widetag)))
-(define-cold-fop (fop-funcall-for-effect nil)
+(define-cold-fop (fop-funcall-for-effect :pushp nil)
(if (= (read-arg 1) 0)
(cold-push (pop-stack)
*current-reversed-cold-toplevels*)
\f
;;;; cold fops for fixing up circularities
-(define-cold-fop (fop-rplaca nil)
+(define-cold-fop (fop-rplaca :pushp nil)
(let ((obj (svref *current-fop-table* (read-arg 4)))
(idx (read-arg 4)))
(write-memory (cold-nthcdr idx obj) (pop-stack))))
-(define-cold-fop (fop-rplacd nil)
+(define-cold-fop (fop-rplacd :pushp nil)
(let ((obj (svref *current-fop-table* (read-arg 4)))
(idx (read-arg 4)))
(write-wordindexed (cold-nthcdr idx obj) 1 (pop-stack))))
-(define-cold-fop (fop-svset nil)
+(define-cold-fop (fop-svset :pushp nil)
(let ((obj (svref *current-fop-table* (read-arg 4)))
(idx (read-arg 4)))
(write-wordindexed obj
(#.sb!vm:other-pointer-lowtag 2)))
(pop-stack))))
-(define-cold-fop (fop-structset nil)
+(define-cold-fop (fop-structset :pushp nil)
(let ((obj (svref *current-fop-table* (read-arg 4)))
(idx (read-arg 4)))
(write-wordindexed obj (1+ idx) (pop-stack))))
-(define-cold-fop (fop-nthcdr t)
+;;; In the original CMUCL code, this actually explicitly declared PUSHP
+;;; to be T, even though that's what it defaults to in DEFINE-COLD-FOP.
+(define-cold-fop (fop-nthcdr)
(cold-nthcdr (read-arg 4) (pop-stack)))
(defun cold-nthcdr (index obj)
;; (SETF CAR).
(make-hash-table :test 'equal))
-(define-cold-fop (fop-fset nil)
+(define-cold-fop (fop-fset :pushp nil)
(let* ((fn (pop-stack))
(cold-name (pop-stack))
(warm-name (warm-fun-name cold-name)))
#!+sb-show
(when *show-pre-fixup-code-p*
(format *trace-output*
- "~&/raw code from code-fop ~D ~D:~%"
+ "~&/raw code from code-fop ~W ~W:~%"
nconst
code-size)
(do ((i start (+ i sb!vm:n-word-bytes)))
(define-cold-code-fop fop-small-code (read-arg 1) (read-arg 2))
-(clone-cold-fop (fop-alter-code nil)
+(clone-cold-fop (fop-alter-code :pushp nil)
(fop-byte-alter-code)
(let ((slot (clone-arg))
(value (pop-stack))
(code (pop-stack)))
(write-wordindexed code slot value)))
-(define-cold-fop (fop-function-entry)
+(define-cold-fop (fop-fun-entry)
(let* ((type (pop-stack))
(arglist (pop-stack))
(name (pop-stack))
sb!vm:fun-pointer-lowtag))
(next (read-wordindexed code-object sb!vm:code-entry-points-slot)))
(unless (zerop (logand offset sb!vm:lowtag-mask))
- ;; FIXME: This should probably become a fatal error.
- (warn "unaligned function entry: ~S at #X~X" name offset))
+ (error "unaligned function entry: ~S at #X~X" name offset))
(write-wordindexed code-object sb!vm:code-entry-points-slot fn)
(write-memory fn
(make-other-immediate-descriptor
;; code instead of a pointer back to the object
;; itself.) Ask on the mailing list whether
;; this is documented somewhere, and if not,
- ;; try to reverse engineer some documentation
- ;; before release.
+ ;; try to reverse engineer some documentation.
#!-x86
;; a pointer back to the function object, as
;; described in CMU CL
(maybe-record-with-translated-name '("-START" "-END") 6)))))
(setf constants
(sort constants
- #'(lambda (const1 const2)
- (if (= (second const1) (second const2))
+ (lambda (const1 const2)
+ (if (= (second const1) (second const2))
(< (third const1) (third const2))
(< (second const1) (second const2))))))
(let ((prev-priority (second (car constants))))
;; writing codes/strings for internal errors
(format t "#define ERRORS { \\~%")
- ;; FIXME: Is this just DOVECTOR?
(let ((internal-errors sb!c:*backend-internal-errors*))
(dotimes (i (length internal-errors))
(format t " ~S, /*~D*/ \\~%" (cdr (aref internal-errors i)) i)))
;; writing primitive object layouts
(let ((structs (sort (copy-list sb!vm:*primitive-objects*) #'string<
- :key #'(lambda (obj)
- (symbol-name
- (sb!vm:primitive-object-name obj))))))
+ :key (lambda (obj)
+ (symbol-name
+ (sb!vm:primitive-object-name obj))))))
(format t "#ifndef LANGUAGE_ASSEMBLY~2%")
(format t "#define LISPOBJ(x) ((lispobj)x)~2%")
(dolist (obj structs)
;; writing static symbol offsets
(dolist (symbol (cons nil sb!vm:*static-symbols*))
- ;; FIXME: It would be nice to use longer names NIL and (particularly) T
- ;; in #define statements.
+ ;; FIXME: It would be nice to use longer names than NIL and
+ ;; (particularly) T in #define statements.
(format t "#define ~A LISPOBJ(0x~X)~%"
(nsubstitute #\_ #\-
- (remove-if #'(lambda (char)
- (member char '(#\% #\* #\. #\!)))
+ (remove-if (lambda (char)
+ (member char '(#\% #\* #\. #\!)))
(symbol-name symbol)))
(if *static* ; if we ran GENESIS
;; We actually ran GENESIS, use the real value.
(format t "#X~8,'0X: ~S~%" (cdr routine) (car routine)))
(let ((funs nil)
(undefs nil))
- (maphash #'(lambda (name fdefn)
- (let ((fun (read-wordindexed fdefn
- sb!vm:fdefn-fun-slot)))
- (if (= (descriptor-bits fun)
- (descriptor-bits *nil-descriptor*))
- (push name undefs)
- (let ((addr (read-wordindexed
- fdefn sb!vm:fdefn-raw-addr-slot)))
- (push (cons name (descriptor-bits addr))
- funs)))))
+ (maphash (lambda (name fdefn)
+ (let ((fun (read-wordindexed fdefn
+ sb!vm:fdefn-fun-slot)))
+ (if (= (descriptor-bits fun)
+ (descriptor-bits *nil-descriptor*))
+ (push name undefs)
+ (let ((addr (read-wordindexed
+ fdefn sb!vm:fdefn-raw-addr-slot)))
+ (push (cons name (descriptor-bits addr))
+ funs)))))
*cold-fdefn-objects*)
(format t "~%~|~%initially defined functions:~2%")
(setf funs (sort funs #'< :key #'cdr))
(format t "~%~|~%layout names:~2%")
(collect ((stuff))
- (maphash #'(lambda (name gorp)
- (declare (ignore name))
- (stuff (cons (descriptor-bits (car gorp))
- (cdr gorp))))
+ (maphash (lambda (name gorp)
+ (declare (ignore name))
+ (stuff (cons (descriptor-bits (car gorp))
+ (cdr gorp))))
*cold-layouts*)
(dolist (x (sort (stuff) #'< :key #'car))
(apply #'format t "~8,'0X: ~S[~D]~%~10T~S~%" x))))
(defparameter validate-entry-type-code 3845)
(defparameter directory-entry-type-code 3841)
(defparameter new-directory-entry-type-code 3861)
-(defparameter initial-function-entry-type-code 3863)
+(defparameter initial-fun-entry-type-code 3863)
(defparameter end-entry-type-code 3840)
-(declaim (ftype (function (sb!vm:word) sb!vm:word) write-long))
-(defun write-long (num) ; FIXME: WRITE-WORD would be a better name.
+(declaim (ftype (function (sb!vm:word) sb!vm:word) write-word))
+(defun write-word (num)
(ecase sb!c:*backend-byte-order*
(:little-endian
(dotimes (i 4)
;; DATA PAGE
;; ADDRESS
;; PAGE COUNT
- (write-long (gspace-identifier gspace))
- (write-long (gspace-free-word-index gspace))
- (write-long *data-page*)
+ (write-word (gspace-identifier gspace))
+ (write-word (gspace-free-word-index gspace))
+ (write-word *data-page*)
(multiple-value-bind (floor rem)
(floor (gspace-byte-address gspace) sb!c:*backend-page-size*)
(aver (zerop rem))
- (write-long floor))
- (write-long pages)
+ (write-word floor))
+ (write-word pages)
(incf *data-page* pages)))
:if-exists :rename-and-delete)
;; Write the magic number.
- (write-long core-magic)
+ (write-word core-magic)
;; Write the Version entry.
- (write-long version-entry-type-code)
- (write-long 3)
- (write-long sbcl-core-version-integer)
+ (write-word version-entry-type-code)
+ (write-word 3)
+ (write-word sbcl-core-version-integer)
;; Write the New Directory entry header.
- (write-long new-directory-entry-type-code)
- (write-long 17) ; length = (5 words/space) * 3 spaces + 2 for header.
+ (write-word new-directory-entry-type-code)
+ (write-word 17) ; length = (5 words/space) * 3 spaces + 2 for header.
(output-gspace *read-only*)
(output-gspace *static*)
(output-gspace *dynamic*)
;; Write the initial function.
- (write-long initial-function-entry-type-code)
- (write-long 3)
+ (write-word initial-fun-entry-type-code)
+ (write-word 3)
(let* ((cold-name (cold-intern '!cold-init))
(cold-fdefn (cold-fdefinition-object cold-name))
- (initial-function (read-wordindexed cold-fdefn
- sb!vm:fdefn-fun-slot)))
+ (initial-fun (read-wordindexed cold-fdefn
+ sb!vm:fdefn-fun-slot)))
(format t
- "~&/(DESCRIPTOR-BITS INITIAL-FUNCTION)=#X~X~%"
- (descriptor-bits initial-function))
- (write-long (descriptor-bits initial-function)))
+ "~&/(DESCRIPTOR-BITS INITIAL-FUN)=#X~X~%"
+ (descriptor-bits initial-fun))
+ (write-word (descriptor-bits initial-fun)))
;; Write the End entry.
- (write-long end-entry-type-code)
- (write-long 2)))
+ (write-word end-entry-type-code)
+ (write-word 2)))
(format t "done]~%")
(force-output)