static.scm 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees
  3. ; This little utility converts a heap image into a C file.
  4. ;
  5. ; For example:
  6. ; (do-it 100000 "~/s48/debug/little.image" "little-heap.c")
  7. ;
  8. ; The first argument to do-it should be somewhat larger than the size,
  9. ; in bytes, of the image file to be converted (which you can obtain with
  10. ; "ls -l").
  11. ;
  12. ; If the image contains 0-length stored objects, then the .c file will
  13. ; have to be compiled by gcc, since 0-length arrays aren't allowed in
  14. ; ANSI C. This wouldn't be difficult to work around.
  15. ;
  16. ; For loading instructions, see load-static.scm.
  17. (define *comments?* #f)
  18. ; 800,000 bytes => 200,000 words => at least 100,000 objects
  19. ; 50 chunks => 16,000 bytes per chunk => 2,000 objects per chunk
  20. (define *chunk-size* 10000)
  21. (define (do-it bytes infile outfile)
  22. (let ((start (init bytes infile)))
  23. (call-with-output-file outfile
  24. (lambda (port)
  25. (format port "#define D(x) (long)(&x)+7~%")
  26. (format port "#define H unsigned long~%")
  27. (emit-area-declarations "p" immutable? "const " port)
  28. (emit-area-declarations "i" mutable? "" port)
  29. (emit-area-initializers "p" immutable? "const " port)
  30. (emit-area-initializers "i" mutable? "" port)
  31. (display "const long entry = " port)
  32. (emit-descriptor start port)
  33. (write-char #\; port)
  34. (newline port)))))
  35. (define (init bytes infile)
  36. (create-memory (quotient bytes 2) quiescent) ;Output of ls -l
  37. (initialize-heap (memory-begin) (memory-size))
  38. (let ((start (read-image infile 0)))
  39. (message (nchunks)
  40. " chunks")
  41. start))
  42. (define (nchunks) (+ (chunk-number (heap-pointer)) 1))
  43. ; emit struct declarations for areas
  44. (define (emit-area-declarations name in-area? const port)
  45. (for-each-stored-object
  46. (lambda (chunk)
  47. (message name chunk " declaration")
  48. (display "struct " port) (display name port) (display chunk port)
  49. (display " {" port) (newline port))
  50. (lambda (x)
  51. (if (in-area? x)
  52. (emit-declaration x port)))
  53. (lambda (chunk)
  54. (display "};" port)
  55. (newline port)
  56. (display const port)
  57. (display "extern struct " port) (display name port) (display chunk port)
  58. (write-char #\space port) (display name port) (display chunk port)
  59. (write-char #\; port) (newline port)
  60. chunk)))
  61. (define (emit-declaration x port)
  62. (display " H x" port)
  63. (writex x port)
  64. (cond ((d-vector? x)
  65. (display "; long d" port)
  66. (writex x port)
  67. (write-char #\[ port)
  68. (write (d-vector-length x) port))
  69. ((vm-string? x)
  70. (display "; char d" port)
  71. (writex x port)
  72. (write-char #\[ port)
  73. ;; Ensure alignment (thanks Ian)
  74. (write (cells->bytes (bytes->cells (b-vector-length x)))
  75. port))
  76. (else
  77. (display "; unsigned char d" port)
  78. (writex x port)
  79. (write-char #\[ port)
  80. ;; Ensure alignment
  81. (write (cells->bytes (bytes->cells (b-vector-length x)))
  82. port)))
  83. (display "];" port)
  84. (if *comments?*
  85. (begin (display " /* " port)
  86. (display (enumerand->name (stob-type x) stob) port)
  87. (display " */" port)))
  88. (newline port))
  89. ; Emit initializers for areas
  90. (define (emit-area-initializers name in-area? const port)
  91. (for-each-stored-object
  92. (lambda (chunk)
  93. (message name chunk " initializer")
  94. (display const port)
  95. (display "struct " port) (display name port) (write chunk port)
  96. (write-char #\space port) (display name port) (write chunk port)
  97. (display " =" port) (newline port)
  98. (write-char #\{ port) (newline port))
  99. (lambda (x)
  100. (if (in-area? x)
  101. (emit-initializer x port)))
  102. (lambda (chunk)
  103. (display "};" port) (newline port)))
  104. (let ((n (nchunks)))
  105. (format port "const long ~a_count = ~s;~%" name n)
  106. (format port "~a long * const ~a_areas[~s] = {" const name n)
  107. (do ((i 0 (+ i 1)))
  108. ((= i n))
  109. (format port "(~a long *)&~a~s, " const name i))
  110. (format port "};~%const long ~a_sizes[~s] = {" name n)
  111. (do ((i 0 (+ i 1)))
  112. ((= i n))
  113. (format port "sizeof(~a~s), " name i))
  114. (format port "};~%")))
  115. (define (message . stuff)
  116. (for-each display stuff) (newline))
  117. (define (emit-initializer x port)
  118. (display " " port)
  119. (write (stob-header x) port)
  120. (write-char #\, port)
  121. (cond ((d-vector? x)
  122. (emit-d-vector-initializer x port))
  123. ((vm-string? x)
  124. (write-char #\" port)
  125. (let ((len (vm-string-length x)))
  126. (do ((i 0 (+ i 1)))
  127. ((= i len) (write-char #\" port))
  128. (let ((c (vm-string-ref x i)))
  129. (cond ((or (char=? c #\") (char=? c #\\))
  130. (write-char #\\ port))
  131. ((char=? c #\newline)
  132. (display "\\n\\" port)))
  133. (write-char c port)))))
  134. (else
  135. (write-char #\{ port)
  136. (let ((len (b-vector-length x)))
  137. (do ((i 0 (+ i 1)))
  138. ((= i len) (write-char #\} port))
  139. (write (b-vector-ref x i) port)
  140. (write-char #\, port)))))
  141. (write-char #\, port)
  142. (if *comments?*
  143. (begin (display " /* " port)
  144. (writex x port)
  145. (display " */" port)))
  146. (newline port))
  147. (define (emit-d-vector-initializer x port)
  148. (write-char #\{ port)
  149. (let ((len (d-vector-length x)))
  150. (do ((i 0 (+ i 1)))
  151. ((= i len) (write-char #\} port))
  152. (emit-descriptor (d-vector-ref x i) port)
  153. (write-char #\, port))))
  154. (define (emit-descriptor x port)
  155. (if (stob? x)
  156. (begin (if (immutable? x)
  157. (display "D(p" port)
  158. (display "D(i" port))
  159. (display (chunk-number x) port)
  160. (display ".x" port)
  161. (writex x port)
  162. (write-char #\) port))
  163. (write x port)))
  164. ; Foo
  165. (define (writex x port)
  166. (write (quotient (- (- x (memory-begin)) 7) 4) port))
  167. (define (chunk-number x)
  168. (quotient (- (- x (memory-begin)) 7) *chunk-size*))
  169. ; Image traversal utility
  170. (define (for-each-stored-object chunk-start proc chunk-end)
  171. (let ((limit (heap-pointer)))
  172. (let chunk-loop ((addr (newspace-begin))
  173. (i 0)
  174. (chunk (+ (newspace-begin) *chunk-size*)))
  175. (if (addr< addr limit)
  176. (begin (chunk-start i)
  177. (let loop ((addr addr))
  178. (if (and (addr< addr limit)
  179. (addr< addr chunk))
  180. (let ((d (fetch addr)))
  181. (if (not (header? d))
  182. (warn "heap is in an inconsistent state" d))
  183. (proc (address->stob-descriptor (addr1+ addr)))
  184. (loop (addr1+ (addr+ addr (header-a-units d)))))
  185. (begin (chunk-end i)
  186. (chunk-loop addr
  187. (+ i 1)
  188. (+ chunk *chunk-size*))))))))))
  189. (define (mutable? x) (not (immutable? x)))