2 (define-module (guile gc))
4 (define (R) (reload-module (current-module)))
7 (define the-cars (make-vector gc-size '(* . *)))
8 (define the-cdrs (make-vector gc-size '(* . *)))
11 (display "\nfree:") (display gc-free) (newline)
12 (display " 0 1 2 3 4 5 6 7 8 9\n")
13 (display "cars:") (display the-cars) (newline)
14 (display "cdrs:") (display the-cdrs) (newline))
17 (display "\nfree:") (display gc-free) (newline)
18 (display " 0 1 2 3 4 5 6 7 8 9\n")
19 (display "ncar:") (display new-cars) (newline)
20 (display "ncdr:") (display new-cdrs) (newline))
24 (vector-ref the-cars (cell-index c)))
27 (vector-ref the-cdrs (cell-index c)))
29 (define (gc-set-car! c x)
30 (if (gc-pair? c) (vector-set! the-cars (cell-index c) x)))
32 (define (gc-set-cdr! c x)
33 (if (gc-pair? c) (vector-set! the-cdrs (cell-index c) x)))
35 (define (gc-null? x) (eq? (car x) 'e))
38 (and (pair? c) (eq? (car c) 'p)))
40 (define (cell-index c)
44 (define (cell-value c)
45 (if (member (car c) '(n s))
48 (define (make-cell type . x)
49 (cons type (if (pair? x) (car x) '*)))
52 (if (= gc-free gc-size) (gc))
54 (set! gc-free (+ gc-free 1))
58 (define (make-number x)
60 (vector-set! the-cars (cell-index cell) (make-cell 'n x))
64 (define (make-symbol x)
66 (vector-set! the-cars (cell-index cell) (make-cell 's x))
72 (vector-set! the-cars (cell-index cell) x)
73 (vector-set! the-cdrs (cell-index cell) y)
77 (define gc-nil (make-cell 'e 0))
78 (define (gc-list . rest)
79 (if (null? rest) gc-nil
80 (gc-cons (car rest) (apply gc-list (cdr rest)))))
82 (define (gc-display x . cont?)
83 (if (gc-pair? x) (begin (if (null? cont?) (display "("))
84 (gc-display (gc-car x))
85 (if (gc-pair? (gc-cdr x)) (display " "))
86 (if (not (gc-null? (gc-cdr x)))
87 (gc-display (gc-cdr x) #t))
88 (if (null? cont?) (display ")")))
89 (if (gc-null? x) (if (not cont?) (display "()"))
90 (display (cell-value x)))))
93 (filter gc-pair? (module-map (lambda (x y) (variable-ref y)) (current-module)))
96 (define new-cars (make-vector (+ gc-size root-size) '(* . *)))
97 (define new-cdrs (make-vector (+ gc-size root-size) '(* . *)))
100 begin-garbage-collection
101 (assign free (const 0))
102 (assign scan (const 0))
103 (assign old (reg root))
104 (assign relocate-continue
105 (label reassign-root))
106 (goto (label relocate-old-result-in-new))
108 (assign root (reg new))
109 (goto (label gc-loop))
112 (test (op =) (reg scan) (reg free))
113 (branch (label gc-flip))
118 (assign relocate-continue
120 (goto (label relocate-old-result-in-new))
124 (perform (op vector-set!)
132 (assign relocate-continue
134 (goto (label relocate-old-result-in-new))
136 (perform (op vector-set!)
140 (assign scan (op +) (reg scan) (const 1))
141 (goto (label gc-loop))
144 relocate-old-result-in-new
145 (test (op pointer-to-pair?) (reg old))
146 (branch (label pair))
147 (assign new (reg old))
148 (goto (reg relocate-continue))
154 (test (op broken-heart?) (reg oldcr))
155 (branch (label already-moved))
156 (assign new (reg free)) ; new location for pair
157 ;; Update ‘free’ pointer.
158 (assign free (op +) (reg free) (const 1))
159 ;; Copy the ‘car’ and ‘cdr’ to new memory.
160 (perform (op vector-set!)
168 (perform (op vector-set!)
172 ;; Construct the broken heart.
173 (perform (op vector-set!)
176 (const broken-heart))
177 (perform (op vector-set!)
181 (goto (reg relocate-continue))
187 (goto (reg relocate-continue))
190 (assign temp (reg the-cdrs))
191 (assign the-cdrs (reg new-cdrs))
192 (assign new-cdrs (reg temp))
193 (assign temp (reg the-cars))
194 (assign the-cars (reg new-cars))
195 (assign new-cars (reg temp))
202 (let ((root (gc-root)))
203 (display "gc root=") (display root) (newline)
206 (gc-loop (gc-relocate root))))
208 (define (gc-loop new)
211 (display "gc-loop new=") (display new) (newline)
212 (display "gc-loop scan=") (display scan) (newline)
213 (display "gc-loop free=") (display gc-free) (newline)
215 (if (eq? scan gc-free) (gc-flip)
216 (let ((old (vector-ref new-cars scan)))
217 (let ((new (gc-relocate old)))
218 (let ((old (gc-update-car new)))
219 (let ((new (gc-relocate old)))
223 (define (gc-update-car new) ; -> old
224 (vector-set! new-cars scan new)
225 (vector-ref new-cdrs scan))
227 (define (gc-update-cdr new)
228 (vector-set! new-cdrs scan new)
229 (set! scan (+ 1 scan)))
231 (define (broken-heart? c) (eq? (car c) '<))
232 (define gc-broken-heart '(< . 3))
233 (define (gc-relocate old) ; old -> new
234 (display "gc-relocate old=") (display old) (newline)
235 (display "gc-relocate old is pair?=") (display (gc-pair? old)) (newline)
237 (if (not (gc-pair? old)) old
238 (let ((oldcr (vector-ref the-cars (cell-index old))))
239 (display "gc-relocate oldcr=") (display oldcr) (newline)
240 (if (broken-heart? oldcr) old
241 (let ((new (cons 'p gc-free)))
242 (set! gc-free (+ 1 gc-free))
243 (vector-set! new-cars (cell-index new) oldcr)
244 (let ((oldcr (vector-ref the-cdrs (cell-index old))))
245 (display "gc-relocate oldcr=") (display oldcr) (newline)
246 (vector-set! new-cdrs (cell-index new) oldcr)
247 (vector-set! the-cars (cell-index old) gc-broken-heart)
248 (vector-set! the-cdrs (cell-index old) new))
252 (let ((cars the-cars)
254 (set! the-cars new-cars)
255 (set! the-cdrs new-cdrs)
257 (set! new-cdrs cdrs))
260 (define first (make-symbol 'F)) (newline)
262 (define one (make-number 1))
263 (display "\n one=") (display one) (newline)
264 (define two (make-number 2))
265 (define pair2-nil (gc-cons two gc-nil))
266 (display "\npair2-nil=") (display pair2-nil) (newline)
269 (define list1-2 (gc-cons one pair2-nil))
270 (display "\nlist1-2=") (display list1-2) (newline)
273 (define three (make-number 3))
274 (define four (make-number 4))
275 (define pair4-nil (gc-cons four gc-nil))
276 (define list3-4 (gc-cons three pair4-nil))
277 (define list1234 (gc-cons list1-2 list3-4))
280 (display "\nlist1-2=") (display list1-2) (newline)
281 (display "\nlist3-4=") (display list3-4) (newline)
282 (display "lst=") (display list1234) (newline)
285 (display "sicp-lst:") (gc-display list1234) (newline)
288 (define next (gc-list (make-symbol 'N) (make-symbol 'X)))
289 (set! list1234 '(p . 0))
290 (display "sicp-lst:") (gc-display list1234) (newline)
292 (display "next=") (display next) (newline)
293 (display "gc-next=") (gc-display next) (newline)