memory2.scm 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey, Jonathan Rees, Mike Sperber
  3. ; An implementation of Pre-Scheme's memory interface that can detect some
  4. ; stray reads and writes. It has numerous limitiations:
  5. ; Allocations are always on page boundaries.
  6. ; No more than 16 megabytes can be allocated at once.
  7. ; More than 32 or 64 or so allocations result in addresses being
  8. ; bignums (dealloctions have no effect on this).
  9. ;
  10. ; Memory is represented as a vector of byte-vectors, with each byte-vector
  11. ; representing a 16-megabyte page. Allocations are always made on page
  12. ; boundaries, so the byte-vectors only need be as large as the allocated
  13. ; areas. Pages are never re-used.
  14. ; Memory is one big vector, with markers at beginning and end of free blocks
  15. ; and allocationg by by address ordered first fit.
  16. ; Strings and things end up as bignums...
  17. (define *memory* (make-vector 0 0))
  18. (define-record-type address :address
  19. (make-address index)
  20. address?
  21. (index address-index))
  22. (define-record-discloser :address
  23. (lambda (addr) (list 'address (address-index addr))))
  24. ; We add 100000000 to addresses to make them
  25. (define address-offset 100000000)
  26. (define (address->integer addr)
  27. (+ (address-index addr) address-offset))
  28. (define (integer->address int)
  29. (make-address (- int address-offset)))
  30. (define (word-ref addr)
  31. (if (address? addr)
  32. (let ((index (address-index addr)))
  33. (if (and (= 0
  34. (vector-ref *memory* (address-index addr)))
  35. (define (word-ref addr)
  36. (vector-ref *memory* (address-index addr)))
  37. (define *memory* (make-vector 16 #f)) ; vector of pages
  38. (define log-max-size 24) ; log of page size
  39. (define address-shift (- log-max-size)) ; turns addresses into page indices
  40. (define max-size (arithmetic-shift 1 log-max-size)) ; page size
  41. (define address-mask ; mask to get address within page
  42. (- (arithmetic-shift 1 log-max-size) 1))
  43. (define *next-index* 0) ; next available page
  44. (define (reinitialize-memory)
  45. (set! *memory* (make-vector 16 #f))
  46. (set! *next-index* 0))
  47. ; Extend the page vector if necessary, and then make a page of the
  48. ; appropriate size.
  49. (define (allocate-memory size)
  50. (cond ((> size max-size)
  51. #f) ; the null pointer
  52. (else
  53. (if (>= *next-index* (vector-length *memory*))
  54. (let ((new (make-vector (* 2 (vector-length *memory*)))))
  55. (do ((i 0 (+ i 1)))
  56. ((>= i (vector-length *memory*)))
  57. (vector-set! new i (vector-ref *memory* i)))
  58. (set! *memory* new)))
  59. (let ((index *next-index*))
  60. (set! *next-index* (+ *next-index* 1))
  61. (vector-set! *memory* index (make-code-vector size 0))
  62. (arithmetic-shift index log-max-size)))))
  63. ; Turning an address into a page or page index
  64. (define (address->vector address)
  65. (vector-ref *memory* (arithmetic-shift address address-shift)))
  66. (define (address->vector-index address)
  67. (bitwise-and address address-mask))
  68. ; Throw away the page containing ADDRESS, which must be the first address in
  69. ; that page,
  70. (define (deallocate-memory address)
  71. (let ((vector (address->vector address))
  72. (byte-address (address->vector-index address)))
  73. (if (and vector (= byte-address 0))
  74. (vector-set! *memory* (arithmetic-shift address address-shift) #f)
  75. (assertion-violation 'deallocate-memory "bad deallocation address" address))))
  76. ; Various ways of accessing memory
  77. (define (unsigned-byte-ref address)
  78. (code-vector-ref (address->vector address)
  79. (address->vector-index address)))
  80. (define (signed-code-vector-ref bvec i)
  81. (let ((x (code-vector-ref bvec i)))
  82. (if (< x 128)
  83. x
  84. (bitwise-ior x -128))))
  85. (define (word-ref address)
  86. (let ((vector (address->vector address))
  87. (byte-address (address->vector-index address)))
  88. (if (not (= 0 (bitwise-and byte-address 3)))
  89. (assertion-violation 'word-ref "unaligned address error" address)
  90. (+ (+ (arithmetic-shift (signed-code-vector-ref vector byte-address) 24)
  91. (arithmetic-shift (code-vector-ref vector (+ byte-address 1)) 16))
  92. (+ (arithmetic-shift (code-vector-ref vector (+ byte-address 2)) 8)
  93. (code-vector-ref vector (+ byte-address 3)))))))
  94. (define (unsigned-byte-set! address value)
  95. (code-vector-set! (address->vector address)
  96. (address->vector-index address)
  97. (bitwise-and 255 value)))
  98. (define (word-set! address value)
  99. (let ((vector (address->vector address))
  100. (byte-address (address->vector-index address)))
  101. (if (not (= 0 (bitwise-and byte-address 3)))
  102. (assertion-violation 'word-set! "unaligned address error" address))
  103. (code-vector-set! vector byte-address
  104. (bitwise-and 255 (arithmetic-shift value -24)))
  105. (code-vector-set! vector (+ byte-address 1)
  106. (bitwise-and 255 (arithmetic-shift value -16)))
  107. (code-vector-set! vector (+ byte-address 2)
  108. (bitwise-and 255 (arithmetic-shift value -8)))
  109. (code-vector-set! vector (+ byte-address 3)
  110. (bitwise-and 255 value))))
  111. ; Block I/O procedures.
  112. (define (write-block port address count)
  113. (let ((vector (address->vector address))
  114. (byte-address (address->vector-index address)))
  115. (do ((i 0 (+ i 1)))
  116. ((>= i count))
  117. (write-char (ascii->char (code-vector-ref vector (+ i byte-address)))
  118. port))
  119. (values count (enum errors no-errors))))
  120. (define (read-block port address count)
  121. (cond ((not (byte-ready? port))
  122. (values 0 #f (enum errors no-errors)))
  123. ((eof-object? (peek-byte port))
  124. (values 0 #t (enum errors no-errors)))
  125. (else
  126. (let ((vector (address->vector address))
  127. (byte-address (address->vector-index address)))
  128. (let loop ((i 0))
  129. (if (or (= i count)
  130. (not (byte-ready? port)))
  131. (values i #f (enum errors no-errors))
  132. (let ((b (read-byte port)))
  133. (cond ((eof-object? b)
  134. (values i #f (enum errors no-errors)))
  135. (else
  136. (code-vector-set! vector
  137. (+ i byte-address)
  138. b)
  139. (loop (+ i 1)))))))))))
  140. (define (copy-memory! from to count)
  141. (let ((from (address-index from))
  142. (to (address-index to)))
  143. (let ((from-vector (address->vector from))
  144. (from-address (address->vector-index from))
  145. (to-vector (address->vector to))
  146. (to-address (address->vector-index to)))
  147. (if (>= from-address to-address)
  148. (do ((i 0 (+ i 1)))
  149. ((>= i count))
  150. (code-vector-set! to-vector
  151. (+ i to-address)
  152. (code-vector-ref from-vector
  153. (+ i from-address))))
  154. (do ((i (- count 1) (- i 1)))
  155. ((negative? i))
  156. (code-vector-set! to-vector
  157. (+ i to-address)
  158. (code-vector-ref from-vector
  159. (+ i from-address))))))))
  160. (define (memory-equal? from to count)
  161. (let ((from-vector (address->vector from))
  162. (from-address (address->vector-index from))
  163. (to-vector (address->vector to))
  164. (to-address (address->vector-index to)))
  165. (let loop ((i 0))
  166. (cond ((>= i count)
  167. #t)
  168. ((= (code-vector-ref to-vector (+ i to-address))
  169. (code-vector-ref from-vector (+ i from-address)))
  170. (loop (+ i 1)))
  171. (else
  172. #f)))))
  173. ; Turn the LENGTH bytes starting from ADDRESS into a string.
  174. (define (char-pointer->string address length)
  175. (let ((vector (address->vector address))
  176. (byte-address (address->vector-index address))
  177. (string (make-string length)))
  178. (do ((i 0 (+ i 1)))
  179. ((= i length))
  180. (string-set! string
  181. i
  182. (ascii->char (code-vector-ref vector (+ byte-address i)))))
  183. string))
  184. ; Turn the bytes from ADDRESS to the next nul (byte equal to 0) into a
  185. ; string. This is a trivial operation in C.
  186. (define (char-pointer->nul-terminated-string address)
  187. (let ((vector (address->vector address))
  188. (byte-address (address->vector-index address)))
  189. (char-pointer->string address (index-of-first-nul vector byte-address))))
  190. (define (index-of-first-nul vector address)
  191. (let loop ((i address))
  192. (cond ((= i (code-vector-length vector))
  193. (assertion-violation 'char-pointer->string
  194. "CHAR-POINTER->STRING called on pointer with no nul termination"))
  195. ((= 0 (code-vector-ref vector i))
  196. (- i address))
  197. (else
  198. (loop (+ i 1))))))
  199. ; We really need these to work.
  200. (define address+ +)
  201. (define address- -)
  202. (define address-difference -)
  203. (define address->integer identity)
  204. (define integer->address identity)
  205. (define ...)