home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / s / s48.zip / VM / DATA.SCM < prev    next >
Text File  |  1992-06-17  |  15KB  |  517 lines

  1. ; -*- Mode: Scheme; Syntax: Scheme; Package: Scheme; -*-
  2. ; Copyright (c) 1992 by Richard Kelsey and Jonathan Rees.  See file COPYING.
  3.  
  4.  
  5. ; This is file data.scm.
  6. ; Requires DEFINE-ENUMERATION macro.
  7.  
  8. ;;;; Data representations
  9.  
  10. ; This implementation of the data representations is particularly
  11. ; tuned for byte-addressable machines with 4 bytes per word.
  12. ; Good representations for other kinds of machines would necessarily
  13. ; look quite different; e.g. on a word-addressed machine you might
  14. ; want to put tag bits in the high end of a word, or even go to some
  15. ; king of BIBOP system.
  16.  
  17.  
  18. ; Descriptors
  19. ;  A descriptor describes a Scheme object.
  20. ;  A descriptor is represented as an integer whose low two bits are
  21. ;  tag bits.  The high bits contain information whose format and
  22. ;  meaning are dependent on the tag.
  23.  
  24. (define tag-field-width 2)
  25. (define data-field-width (- bits-per-cell tag-field-width))
  26.  
  27. (define (make-descriptor tag data)
  28.   (adjoin-bits data tag tag-field-width))
  29.  
  30. (define (descriptor-tag descriptor)
  31.   (low-bits descriptor tag-field-width))
  32.  
  33. (define (descriptor-data descriptor)
  34.   (high-bits descriptor tag-field-width))
  35.  
  36. (define (set-descriptor-tag! proto-descriptor tag)
  37.   (assert (= 0 (descriptor-tag proto-descriptor)))
  38.   (+ proto-descriptor tag))
  39.  
  40. (define vm-eq? =)
  41.  
  42. ; The four tags are: fixnum, immediate (character, boolean, etc.),
  43. ; header (gives the type and size of a stored object), and stored
  44. ; (pointer into memory).
  45. ; The header and immediate tags could be multiplexed, thus freeing up
  46. ; one of the 4 type codes for some other purpose, but the
  47. ; implementation is simpler if they're not.
  48.  
  49. (define-enumeration tag
  50.   (fixnum
  51.    immediate
  52.    header
  53.    stob))
  54.  
  55. ;; (assert (>= (ashl 1 tag-field-width)
  56. ;;             (vector-length tag)))
  57.  
  58. (define (fixnum? descriptor)
  59.   (= (descriptor-tag descriptor) tag/fixnum))
  60.  
  61. (define (immediate? descriptor)
  62.   (= (descriptor-tag descriptor) tag/immediate))
  63.  
  64. (define (header? descriptor)
  65.   (= (descriptor-tag descriptor) tag/header))
  66.  
  67. (define (stob? descriptor)
  68.   (= (descriptor-tag descriptor) tag/stob))
  69.  
  70. ; Fixnums
  71.  
  72. (define bits-per-fixnum
  73.   (- (if (< bits-per-cell useful-bits-per-word)
  74.           bits-per-cell
  75.           useful-bits-per-word)
  76.       tag-field-width))
  77.  
  78. (define    least-fixnum-value (- 0 (ashl 1 (- bits-per-fixnum 1))))
  79. (define greatest-fixnum-value (-   (ashl 1 (- bits-per-fixnum 1)) 1))
  80.  
  81. (define (too-big-for-fixnum? n)
  82.   (> n greatest-fixnum-value))
  83.  
  84. (define (too-small-for-fixnum? n)
  85.   (< n least-fixnum-value))
  86.  
  87. (define (overflows? n)
  88.   (or (too-big-for-fixnum? n)
  89.       (too-small-for-fixnum? n)))
  90.  
  91. (define (enter-fixnum n)
  92.   (assert (not (overflows? n)))
  93.   (make-descriptor tag/fixnum n))
  94.  
  95. (define (extract-fixnum p)
  96.   (assert (fixnum? p))
  97.   (descriptor-data p))
  98.  
  99. ; Generic number stuff
  100.  
  101. (define (vm-number? x)
  102.   (or (fixnum? x)
  103.       (extended-number? x)))
  104.  
  105. (define (carefully op)
  106.   (lambda (x y succ fail)
  107.     (let ((z (op (extract-fixnum x) (extract-fixnum y))))
  108.       (if (overflows? z)
  109.           (fail x y)
  110.           (succ (enter-fixnum z))))))
  111.  
  112. (define add-carefully (carefully +))
  113. (define subtract-carefully (carefully -))
  114.  
  115. (define half-word-size (quotient bits-per-fixnum 2))
  116. (define half-word-mask (- (ashl 1 half-word-size) 1))
  117. (define max-middle (- (ashl 1 (+ 1 (- bits-per-fixnum half-word-size)))
  118.                1))
  119.  
  120. (define (multiply-carefully x y succ fail)
  121.   (let* ((a (extract-fixnum x))
  122.          (b (extract-fixnum y))
  123.          (positive-result? (if (>= a 0)
  124.                                (>= b 0)
  125.                                (< b 0)))
  126.          (a (abs a))
  127.          (b (abs b))
  128.      (lo-a (bitwise-and half-word-mask a))
  129.      (lo-b (bitwise-and half-word-mask b))
  130.          (hi-a (bitwise-and half-word-mask (high-bits a half-word-size)))
  131.          (hi-b (bitwise-and half-word-mask (high-bits b half-word-size)))
  132.      (lo-c (* lo-a lo-b))
  133.      (mid-c (+ (* lo-a hi-b) (* lo-b hi-a)))
  134.      (c (+ lo-c (ashl mid-c half-word-size))))
  135.     (cond ((or (and (> hi-a 0) (> hi-b 0))
  136.            (too-big-for-fixnum? lo-c)
  137.            (> mid-c max-middle))
  138.        (fail x y))
  139.       (positive-result?
  140.        (if (too-big-for-fixnum? c)
  141.            (fail x y)
  142.            (succ (enter-fixnum c))))
  143.       (else
  144.        (if (too-small-for-fixnum? (- 0 c))
  145.            (fail x y)
  146.            (succ (enter-fixnum (- 0 c))))))))
  147.  
  148. ; Test cases for bits-per-cell = 28, bits-per-fixnum = 26
  149.  
  150. ;   (do ((i 2 (* i 2))
  151. ;        (j (* -2 (expt 2 23)) (/ j 2)))
  152. ;       ((>= j 0) 'ok)
  153. ;     (write `((* ,i ,j) ?=? ,(* i j)))
  154. ;     (newline))
  155.  
  156. (define (divide-carefully x y succ fail)
  157.   (quotient-carefully x y
  158.                       (lambda (q)
  159.                         (remainder-carefully x y
  160.                                              (lambda (r)
  161.                                                (if (= r (enter-fixnum 0))
  162.                                                    (succ q)
  163.                                                    (fail x y)))
  164.                                              fail))
  165.                       fail))
  166.  
  167. ; Watch out for (quotient least-fixnum -1)
  168. (define (quotient-carefully x y succ fail)
  169.   (if (= y (enter-fixnum 0))
  170.       (fail x y)
  171.       (let* ((a (extract-fixnum x))
  172.          (b (extract-fixnum y))
  173.          (positive-result? (if (>= a 0)
  174.                    (>= b 0)
  175.                    (< b 0)))
  176.          (a (abs a))
  177.          (b (abs b))
  178.          (c (quotient a b)))
  179.     (cond ((not positive-result?)
  180.            (succ (enter-fixnum (- 0 c))))
  181.           ((too-big-for-fixnum? c)  ; (quotient least-fixnum -1)
  182.            (fail x y))
  183.           (else
  184.            (succ (enter-fixnum c)))))))
  185.  
  186. ; Overflow check not necessary
  187. (define (remainder-carefully x y succ fail)
  188.   (if (= y (enter-fixnum 0))
  189.       (fail x y)
  190.       (let* ((a (extract-fixnum x))
  191.          (b (extract-fixnum y))
  192.          (positive-result? (>= a 0))
  193.          (a (abs a))
  194.          (b (abs b))
  195.          (c (remainder a b)))
  196.     (succ (enter-fixnum (if positive-result? c (- 0 c)))))))
  197.  
  198. ; These happen to work out, given our representation for fixnums.
  199. (define vm-= =)
  200. (define vm-< <)
  201.  
  202. ; Immediates
  203. ;  The number 8 is chosen to streamline 8-bit-byte-oriented implementations.
  204.  
  205. (define immediate-type-field-width
  206.   (- 8 tag-field-width))
  207.  
  208. (define (make-immediate type info)
  209.   (make-descriptor tag/immediate
  210.                    (adjoin-bits info type immediate-type-field-width)))
  211.  
  212. (define (immediate-type imm)
  213.   (assert (immediate? imm))
  214.   (low-bits (descriptor-data imm)
  215.              immediate-type-field-width))
  216.  
  217. (define (immediate-info imm)
  218.   (assert (immediate? imm))
  219.   (high-bits (descriptor-data imm)
  220.               immediate-type-field-width))
  221.  
  222. (define (tag&immediate-type descriptor)
  223.   (low-bits descriptor (+ tag-field-width immediate-type-field-width)))
  224.  
  225. (define (make-tag&immediate-type type)
  226.   (adjoin-bits type tag/immediate tag-field-width))
  227.  
  228. (define-enumeration imm
  229.   (false      ; #f
  230.    true       ; #t
  231.    char
  232.    unspecified
  233.    undefined
  234.    eof
  235.    null))
  236.  
  237. ;; (assert (>= (ashl 1 immediate-type-field-width)
  238. ;;             (vector-length imm)))
  239.  
  240. (define (immediate-predicate type)
  241.   (lambda (descriptor)
  242.     ;; Check low 8 bits...
  243.     (= (tag&immediate-type descriptor)
  244.     (make-tag&immediate-type type))))
  245.  
  246. (define false?     (immediate-predicate imm/false))
  247. (define vm-char?   (immediate-predicate imm/char))
  248. (define undefined? (immediate-predicate imm/undefined))
  249.  
  250. (define true          (make-immediate imm/true 0))
  251. (define false         (make-immediate imm/false 0))
  252. (define eof-object    (make-immediate imm/eof  0))
  253. (define null          (make-immediate imm/null 0))
  254. (define unspecified   (make-immediate imm/unspecified 0))
  255. (define quiescent         (make-immediate imm/undefined 0))
  256. (define unbound-marker    (make-immediate imm/undefined 1))
  257. (define unassigned-marker (make-immediate imm/undefined 2))
  258.  
  259. (define (enter-boolean b)
  260.   (if b true false))
  261.  
  262. (define (extract-boolean b)
  263.   (assert (boolean? b))
  264.   (if (vm-eq? b false) #f #t))
  265.  
  266. (define (boolean? x)
  267.   (or (vm-eq? x false)
  268.       (vm-eq? x true)))
  269.  
  270. ; Characters
  271.  
  272. (define (enter-char c)
  273.   (make-immediate imm/char (char->ascii c)))
  274.  
  275. (define (extract-char d)
  276.   (assert (vm-char? d))
  277.   (ascii->char (immediate-info d)))
  278.  
  279. (define vm-char=? char=?)
  280. (define vm-char<? char<?)
  281. (define vm-char->ascii char->ascii)
  282. (define vm-ascii->char ascii->char)
  283.  
  284. ; Headers
  285. ;  The possible values for the type field are defined elsewhere.
  286. ;  *** Eventually allow for an immutability bit, to prevent people
  287. ;      from clobbering symbol names and quoted structure.
  288.  
  289. (define header-type-field-width (- immediate-type-field-width 1))
  290.  
  291. (define (make-header type length-in-bytes)
  292.   (make-descriptor tag/header (adjoin-bits length-in-bytes
  293.                                             type
  294.                                             header-type-field-width)))
  295.  
  296. (define (header-type h)
  297.   (assert (header? h))
  298.   (low-bits (descriptor-data h)
  299.              header-type-field-width))
  300.  
  301. (define (header-length-in-bytes h)
  302.   (assert (header? h))
  303.   (high-bits (descriptor-data h)
  304.               header-type-field-width))
  305.  
  306. (define (header-length-in-cells header)
  307.   (bytes->cells (header-length-in-bytes header)))
  308.  
  309. (define (header-a-units h)   ;Used by GC to find end of any object
  310.   (bytes->a-units (header-length-in-bytes h)))
  311.  
  312. ; Stored objects
  313. ;  The data field of a descriptor for a stored object contains the
  314. ;  cell number of the first cell after the object's header cell.
  315.  
  316. ;;; Moved from STRUCT to get LEAST-B-VECTOR-TYPE in this file.
  317.  
  318. (define-enumeration stob
  319.   (;; D-vector types (traced by GC)
  320.    pair
  321.    symbol
  322.    vector
  323.    closure
  324.    location
  325.    port
  326.    ratio
  327.    record
  328.    continuation
  329.    extended-number
  330.  
  331.    ;; B-vector types (not traced by GC)
  332.    string        ; = least b-vector type
  333.    code-vector
  334.    double        ; double precision floating point
  335.    bignum
  336.    ))
  337.  
  338. (define least-b-vector-type stob/string)
  339.  
  340. (define (make-stob-descriptor addr)
  341.   (set-descriptor-tag! addr tag/stob))
  342.  
  343. (define (address-at-header stob)
  344.   (assert (stob? stob))
  345.   (- stob (+ tag/stob addressing-units-per-cell))) 
  346.  
  347. (define (address-after-header stob)
  348.   (assert (stob? stob))
  349.   (- stob tag/stob))
  350.  
  351. (define (stob-length-in-bytes stob)
  352.   (header-length-in-bytes (stob-header stob)))
  353.  
  354. (define (address-after-stob stob)
  355.   (addr+ (address-after-header stob)
  356.          (bytes->a-units (stob-length-in-bytes stob))))
  357.  
  358. ; Accessing memory via stob descriptors
  359.  
  360. (define (stob-ref stob index)
  361.   (fetch (addr+ (address-after-header stob) (cells->a-units index))))
  362.  
  363. (define (stob-set! stob index value)
  364.   (store! (addr+ (address-after-header stob) (cells->a-units index))
  365.           value))
  366.  
  367. (define (stob-header stob)
  368.   (stob-ref stob -1))
  369.  
  370. (define (stob-header-set! stob header)
  371.   (stob-set! stob -1 header))
  372.  
  373. (define (stob-type obj)
  374.   (header-type (stob-header obj)))
  375.  
  376. (define (stob-of-type? obj type)
  377.   (and (stob? obj)
  378.        (= (stob-type obj) type)))
  379.  
  380. (define (stob-equal? stob1 stob2)    ;CMPC3 loop or "strncmp"
  381.   (let ((z1 (stob-header stob1))
  382.         (z2 (stob-header stob2)))
  383.     (and (= z1 z2)
  384.          (let ((z (header-length-in-cells z1)))
  385.            (let loop ((i 0))
  386.              (cond ((>= i z) #t)
  387.                    ((= (stob-ref stob1 i)
  388.                         (stob-ref stob2 i))
  389.                     (loop (+ i 1)))
  390.                    (else #f)))))))
  391.  
  392. (define (valid-index? index len)
  393.   (and (>= index 0) (< index len)))
  394.  
  395. ; Allocation
  396. ;  *hp* is the heap pointer and *limit* is the limit beyond which no
  397. ;  storage should be allocated.  Both of these are addresses (not
  398. ;  descriptors).
  399.  
  400. (define check-preallocation? #f)
  401.  
  402. (define *hp* 0)
  403. (define *limit* 0)
  404.  
  405. (define (available? cells)
  406.   (addr< (addr+ *hp* (cells->a-units cells)) *limit*))
  407.  
  408. (define (available)
  409.   (a-units->cells (addr- *limit* *hp*)))
  410.  
  411. (define *heap-key* 0)
  412. (define universal-key 0)
  413. (define *okayed-space* 0)
  414.  
  415. (define (preallocate-space cells)
  416.   (cond (check-preallocation?
  417.      (assert (available? cells))
  418.      (set! *heap-key* (+ *heap-key* 1))
  419.      (set! *okayed-space* cells)
  420.      *heap-key*)
  421.     (else
  422.      universal-key)))
  423.  
  424. (define (make-stob type len key)    ;len is in bytes
  425.   (if check-preallocation?
  426.       (let ((cells (+ (bytes->cells len) 1)))
  427.     (assert (available? cells))
  428.     (cond ((= key universal-key) 0)
  429.           ((not (and (= key *heap-key*)
  430.              (>= *okayed-space* cells)))
  431.            (error "invalid heap key" key cells))
  432.           (else
  433.            (set! *okayed-space* (- *okayed-space* cells))))))
  434.   (store! *hp* (make-header type len))  ;(store-next!)
  435.   (set! *hp* (addr1+ *hp*))
  436.   (let ((new (make-stob-descriptor *hp*)))
  437.     (set! *hp* (addr+ *hp* (bytes->a-units len)))
  438.     (if (> len 0)            ; for B-VECTORs that don't want to use all of the
  439.         (store! (addr+ *hp* (cells->bytes -1)) 0)) ; last descriptor
  440.     new))                               ; use all of the last descriptor
  441.  
  442. (define (copy-stob stob key)
  443.   (assert (stob? stob))
  444.   (let ((new (make-stob (header-type (stob-header stob))
  445.             (header-length-in-bytes (stob-header stob))
  446.             key)))
  447.     (copy-stob! stob new)
  448.     new))  
  449.  
  450. (define (copy-stob! from to)
  451.   (copy-cells! (address-after-header from)
  452.                (address-after-header to)
  453.                (bytes->cells (stob-length-in-bytes from))))
  454.  
  455. (define (copy-cells! from to count)
  456.   (let ((end (addr+ from (cells->a-units count))))
  457.     (do ((from from (addr1+ from))
  458.          (to to (addr1+ to)))
  459.         ((>= from end))
  460.       (store! to (fetch from)))))
  461.  
  462. ; D-vectors (vectors of descriptors)
  463.  
  464. (define (d-vector-header? h)
  465.   (< (header-type h) least-b-vector-type))
  466.  
  467. (define (d-vector? obj)
  468.   (and (stob? obj)
  469.        (< (header-type (stob-header obj)) least-b-vector-type)))
  470.  
  471. (define (make-d-vector type len key)
  472.   (make-stob type (cells->bytes len) key))
  473.  
  474. ; The type in these routines is used only for internal error checking.
  475.  
  476. (define (d-vector-length x)
  477.   (assert (d-vector? x))
  478.   (header-length-in-cells (stob-header x)))
  479.  
  480. (define (d-vector-ref x index)
  481.   (assert (valid-index? index (d-vector-length x)))
  482.   (stob-ref x index))
  483.  
  484. (define (d-vector-set! x index val)
  485.   (assert (valid-index? index (d-vector-length x)))
  486.   (stob-set! x index val))
  487.  
  488. ; B-vector = vector of bytes.
  489.  
  490. (define (b-vector-header? h)
  491.   (and (header? h)
  492.        (>= (header-type h) least-b-vector-type)))
  493.  
  494. (define (b-vector? obj)
  495.   (and (stob? obj)
  496.        (>= (header-type (stob-header obj))
  497.             least-b-vector-type)))
  498.  
  499. (define make-b-vector make-stob)
  500.  
  501. (define (b-vector-length x)
  502.   (assert (b-vector? x))
  503.   (header-length-in-bytes (stob-header x)))
  504.  
  505.  
  506. (define (b-vector-ref b-vector index)
  507.   (assert (valid-index? index (b-vector-length b-vector)))
  508.   (fetch-byte (addr+ (address-after-header b-vector) index)))
  509.  
  510. (define (b-vector-set! b-vector index value)
  511.   (assert (valid-index? index (b-vector-length b-vector)))
  512.   (store-byte! (addr+ (address-after-header b-vector) index) value))
  513.  
  514.  
  515.  
  516.  
  517.