6.001/Recitation 13
Rob Speer
< 6.001
Contents |
[edit]
Garbage collection
We're going to do garbage collection in a hypothetical Scheme world where pairs and atoms really are the only data types, except we have two big vectors to represent the pairs.
[edit]
Reference counting
- Tack on a count to every pair that says how many things point to it.
- Garbage collect things with 0 references.
- It's easy! It's fast! It doesn't always work!
[edit]
Mark and sweep
- Mark the root
- Whenever you mark something, recursively mark its car and cdr
- Scan all of memory and check for unmarked cells
- Join unmarked cells together into free list
(define (mark obj)
(cond ((not (pair? object)) #f)
((not (= 1 (vector-ref the-marks object)))
(vector-set! the-marks object 1)
(mark (car object))
(mark (cdr object)))))
(define (sweep i)
(cond ((not (< i 0))
(if (= 1 (vector-ref the-marks i))
(vector-set! the-marks i 0)
(begin
(set-cdr! (int-to-pointer i) free)
(set! free (int-to-pointer i))))
(sweep (- i 1)))))
(define (gc root)
(mark root)
(sweep (vector-size the-cars)))
- You can make a
consthat uses the free list - Can have stack issues
[edit]
Stop and copy
- Set free and scan to point to beginning of new memory (new-cars, new-cdrs)
- "Forward" the root pointer
- Scan through new memory looking up each pointer, and forwarding those too
- Mark forwarded pairs with a symbol ("broken heart") in the car, and the forwarding pointer in the cdr
- Increment scan and repeat until catches up to free
- How to forward
- look up pointers in old memory
- relocate car
- relocate cdr
- How to relocate
- If it's forwarded already, just look up new address
- copy into free pair
- increment free
- store forwarding pointer
(define (stop-and-copy root)
(let ((free 0))
(define (gccopy scan)
(if (not (= scan free))
(begin
(vector-set! the-cars scan (forward (vector-ref the-cars scan)))
(vector-set! the-cdrs scan (forward (vector-ref the-cdrs scan)))
(gccopy (+ scan 1)))))
(define (forward pointer)
(if (not (pair? pointer))
pointer
(let (oldcar (car pointer))
(if (forwarded? oldcar)
(int-to-pointer oldcar)
(begin
(vector-set! new-cars free oldcar)
(vector-set! new-cdrs free (cdr pointer))
(set! free (+ 1 free))
(set-car! pointer (int-to-pointer free)))))))
(forward root)
(gccopy 0)
(swap the-cars new-cars)
(swap the-cdrs new-cdrs)))
