read-image.scm 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; Read-image
  3. (define (s48-read-image image-filename max-heap-size)
  4. (init-read-image!)
  5. (receive (port status)
  6. (open-input-file image-filename)
  7. (if (error? status)
  8. (begin
  9. (error-message "Can't open heap image file")
  10. (error-message (error-string status))
  11. -1)
  12. (receive (status format)
  13. (check-image-header port)
  14. (cond
  15. ;; Read in the ASCII portion of the image and make
  16. ;; sure that it is compatible with this version of
  17. ;; the VM.
  18. ((got-error? status) -1)
  19. ;; now we can initialize the heap
  20. ((got-error? (initialize-heap! max-heap-size)) -1)
  21. ;; allocate space and copy the objects (image => heap)
  22. ((got-error? (read-image-to-heap format port)) -1)
  23. (else 0)))))) ; Everything OK
  24. ; reads image objects into the heap object
  25. (define (read-image-to-heap image-format port)
  26. (really-read-image image-format (check-byte-order port) port))
  27. (define (check-byte-order port)
  28. (let ((new-addr (allocate-memory (cells->bytes 1))))
  29. (receive (okay? msg)
  30. (image-read-block port new-addr (cells->a-units 1))
  31. (if (not okay?)
  32. (error "byte order check failed"))
  33. (cond ((= (fetch new-addr) false)
  34. (deallocate-memory new-addr)
  35. #f)
  36. (else
  37. (reverse-descriptor-byte-order! new-addr)
  38. (if (not (= (fetch new-addr) false))
  39. (error "Unable to correct byte order"))
  40. (deallocate-memory new-addr)
  41. #t)))))
  42. (define (check-image-header port)
  43. ;; Skip page-char (start of the image-header)
  44. (read-check (read-page port))
  45. ;; Skip newline-char (version starts on next line)
  46. (read-check (read-newline port))
  47. ;; Read version, bytes/cell and co.
  48. (let* ((same-version? (read-check (check-image-version port) #f))
  49. (format (read-check (check-image-format port) -1))
  50. (old-bytes-per-cell (read-check (read-integer port))))
  51. ;; Is everything OK?
  52. (values (cond ((error? (get-status))
  53. (read-lost "Error reading from image file" port))
  54. ((is-eof?) ; has to come after *status* check
  55. (set-status! (enum errors parse-error))
  56. (read-lost "Premature EOF when reading image file" port))
  57. ((not same-version?)
  58. (read-lost "Format of image is incompatible with this version of system"
  59. port))
  60. ((not (valid-image-format? format))
  61. (read-lost "Unknown image format" port))
  62. ((not (= old-bytes-per-cell bytes-per-cell))
  63. (read-lost "Incompatible bytes-per-cell in image" port))
  64. (else
  65. (check-all-data! format port)
  66. (set-symbols! (read-check (read-integer port)))
  67. (set-imported-bindings! (read-check (read-integer port)))
  68. (set-exported-bindings! (read-check (read-integer port)))
  69. (set-resumer-records! (read-check (read-integer port)))
  70. (set-startup-procedure! (read-check (read-integer port)))
  71. ;; Skip page-char (end of the image-header = begin of image-heap)
  72. (read-check (read-page port))
  73. 0))
  74. format)))
  75. (define (check-image-version port)
  76. (let ((len (string-length architecture-version)))
  77. (let loop ((i 0))
  78. (receive (ch eof? status)
  79. (read-char port)
  80. (cond ((or eof? (error? status))
  81. (values #f eof? status))
  82. ((= i len)
  83. (values (char=? #\newline ch) #f status))
  84. ((char=? ch (string-ref architecture-version i))
  85. (loop (+ i 1)))
  86. (else
  87. (values #f #f status)))))))
  88. (define (check-image-format port)
  89. (receive (n eof? status)
  90. (read-integer port)
  91. (values n eof? status)))
  92. (define (check-all-data! format port)
  93. (enum-case image-format format
  94. ((two-space)
  95. (set-img-start-addr!
  96. (integer->address
  97. (cells->a-units (read-check (read-integer port)))))
  98. (set-img-end-addr!
  99. (integer->address
  100. (cells->a-units (read-check (read-integer port)))))
  101. (set-img-heap-size!
  102. (bytes->cells (address-difference (get-img-end-addr)
  103. (get-img-start-addr)))))
  104. ((bibop)
  105. ;; Read all to calculate the real size
  106. (let* ((sb (cells->a-units (read-check (read-integer port))))
  107. (sh (cells->a-units (read-check (read-integer port))))
  108. (se (cells->a-units (read-check (read-integer port))))
  109. (lb se)
  110. (lh (cells->a-units (read-check (read-integer port))))
  111. (le (cells->a-units (read-check (read-integer port))))
  112. (wb le)
  113. (wh (cells->a-units (read-check (read-integer port))))
  114. (we (cells->a-units (read-check (read-integer port)))))
  115. (set-small-img-start-addr! (integer->address sb))
  116. (set-small-img-hp-addr! (integer->address sh))
  117. (set-small-img-end-addr! (integer->address se))
  118. (set-large-img-start-addr! (integer->address lb))
  119. (set-large-img-hp-addr! (integer->address lh))
  120. (set-large-img-end-addr! (integer->address le))
  121. (set-weaks-img-start-addr! (integer->address wb))
  122. (set-weaks-img-hp-addr! (integer->address wh))
  123. (set-weaks-img-end-addr! (integer->address we))
  124. ;; These are going to be read from the image (port)
  125. (set-small-img-heap-size! (a-units->cells (- sh sb)))
  126. (set-large-img-heap-size! (a-units->cells (- lh lb)))
  127. (set-weaks-img-heap-size! (a-units->cells (- wh wb)))
  128. ;; This image is WLS
  129. (set-img-start-addr! (integer->address wb))
  130. (set-img-end-addr! (integer->address sh))
  131. ;; This is going to be allocated (so we need the
  132. ;; real whole size to have 1:1 addresses)
  133. (set-img-heap-size! (+ (a-units->cells (- se sb))
  134. (a-units->cells (- le lb))
  135. (a-units->cells (- we wb))))))
  136. (else (error "check-all-data!: Unknown image format (this can't happen)"))))
  137. (define (initialize-heap! max-heap-size)
  138. (s48-initialize-heap max-heap-size
  139. (get-img-start-addr) (get-img-heap-size))
  140. (initialize-image-areas!)
  141. (s48-check-heap-size!)
  142. 0) ; for the type checker
  143. ;----------------
  144. ; Save initial values across any GC's.
  145. (define *initializing?* #t)
  146. (define (s48-initializing-gc-root)
  147. (if *initializing?*
  148. (begin
  149. (set-startup-procedure! (s48-trace-value (get-startup-procedure)))
  150. (set-symbols! (s48-trace-value (get-symbols)))
  151. (set-imported-bindings! (s48-trace-value (get-imported-bindings)))
  152. (set-exported-bindings! (s48-trace-value (get-exported-bindings)))
  153. (set-resumer-records! (s48-trace-value (get-resumer-records))))))
  154. ; For the outside world.
  155. (define (s48-startup-procedure) (get-startup-procedure))
  156. (define (s48-initial-symbols) (get-symbols))
  157. (define (s48-initial-imported-bindings) (get-imported-bindings))
  158. (define (s48-initial-exported-bindings) (get-exported-bindings))
  159. (define (s48-resumer-records) (get-resumer-records))
  160. (define (s48-initialization-complete!)
  161. (set! *initializing?* #f))
  162. ; For resuming static images.
  163. (define (s48-set-image-values! startup-proc symbols imports exports records)
  164. (set-startup-procedure! startup-proc)
  165. (set-symbols! symbols)
  166. (set-imported-bindings! imports)
  167. (set-exported-bindings! exports)
  168. (set-resumer-records! records))
  169. ; #### needs to be generalized
  170. ; (define (s48-relocate-all delta new-begin new-hp symbols imported exported)
  171. ; (relocate-symbol-table-two-space! symbols delta)
  172. ; (relocate-binding-table-two-space! imported delta)
  173. ; (relocate-binding-table-two-space! exported delta)
  174. ; (relocate-image delta new-begin new-hp))
  175. ; for debugging
  176. (define (get-all-globals)
  177. (write-out-string "(get-status): ")
  178. (if (eq? (get-status)
  179. (enum errors no-errors))
  180. (write-out-string "no-errors ")
  181. (write-out-string "errors "))
  182. (write-out-newline)
  183. (write-out-string "(is-eof?): ")
  184. (if (is-eof?)
  185. (write-out-string "EOF ")
  186. (write-out-string "NOT EOF "))
  187. (write-out-newline)
  188. (write-out-string "null-address: ")
  189. (write-out-integer (address->integer null-address))
  190. (write-out-newline)
  191. (write-out-string "(get-img-start-addr): ")
  192. (write-out-integer (address->integer (get-img-start-addr)))
  193. (write-out-newline)
  194. (write-out-string "(get-img-end-addr): ")
  195. (write-out-integer (address->integer (get-img-end-addr)))
  196. (write-out-newline)
  197. (write-out-string "(get-img-heap-size): ")
  198. (write-out-integer (get-img-heap-size))
  199. (write-out-newline)
  200. (write-out-string "(get-startup-procedure): ")
  201. (write-out-integer (get-startup-procedure))
  202. (write-out-newline)
  203. (write-out-string "(get-symbols): ")
  204. (write-out-integer (get-symbols))
  205. (write-out-newline)
  206. (write-out-string "(get-imported-bindings): ")
  207. (write-out-integer (get-imported-bindings))
  208. (write-out-newline)
  209. (write-out-string "(get-exported-bindings): ")
  210. (write-out-integer (get-exported-bindings))
  211. (write-out-newline)
  212. (write-out-string "(get-resumer-records): ")
  213. (write-out-integer (get-resumer-records))
  214. (write-out-newline)
  215. )