From 21edc13b1e2ddb47e8c9947cd0f80dad95f2d7cd Mon Sep 17 00:00:00 2001 From: Isaac Shoebottom Date: Thu, 24 Apr 2025 11:55:13 -0300 Subject: [PATCH] WIP 3.rkt --- Final/3.rkt | 81 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 10 deletions(-) diff --git a/Final/3.rkt b/Final/3.rkt index 9b7de0c..5b1a48b 100644 --- a/Final/3.rkt +++ b/Final/3.rkt @@ -58,8 +58,16 @@ (test/exn (begin oper ...) expected))))])) (define (swap-spaces!) - ;; do nothing - (void)) + (let ([current-offset (off)]) + (if (= current-offset METADATA-SIZE) + ;; If left semi-space, switch to the right + (begin + (heap-set! LOC:OFFSET (+ METADATA-SIZE (space-size))) + (heap-set! LOC:PTR 0)) + ;; Else switch back to the left semi-space + (begin + (heap-set! LOC:OFFSET METADATA-SIZE) + (heap-set! LOC:PTR 0))))) (module+ test @@ -89,17 +97,70 @@ ) ;; malloc : size -> address -(define (malloc n) - (when (> (+ (ptr) n) (space-size)) +(define (malloc n . other-roots) + (when (> (+ (ptr) n (length other-roots)) (space-size)) (gc!)) - (when (> (+ (ptr) n) (space-size)) + (when (> (+ (ptr) n (length other-roots)) (space-size)) (error 'malloc "out of memory!")) - (heap-set! LOC:PTR (+ (ptr) n)) - (+ (heap-ref LOC:OFFSET) (- (ptr) n))) + (heap-set! LOC:PTR (+ (ptr) n (length other-roots))) + (+ (heap-ref LOC:OFFSET) (- (ptr) n (length other-roots)))) -(define (gc!) - ;; do nothing - (void)) +(define (forward/root thing) + (define addr (read-root thing)) + (cond + [(gc:flat? addr) (gc:alloc-flat (gc:deref addr))] + [(gc:cons? addr) (gc:cons (gc:first thing) (gc:rest addr))] + [(gc:closure? addr) (gc:closure (gc:closure-code-ptr addr) (empty))])) + +(define (forward/loc thing) + (define tag (heap-ref thing)) + (cond + [(equal? tag 'forwarded) + (void)] + [(equal? tag 'flat) + (heap-set! thing 'forwarded) + (heap-set! (+ thing 1) (gc:alloc-flat (heap-ref (+ thing 1))))] + [(equal? tag 'cons) + (heap-set! thing 'forwarded) + (heap-set! (+ thing 1) (gc:cons + (simple-root (heap-ref (+ thing 1))) + (simple-root (heap-ref (+ thing 2)))))] + [(equal? tag 'clos) + (let* ([code-ptr (heap-ref (+ thing 1))] + [n-vars (heap-ref (+ thing 2))] + [free-vars (for/list ([i (in-range n-vars)]) + (simple-root (heap-ref (+ thing 3 i))))]) + (heap-set! thing 'forwarded) + (heap-set! (+ thing 1) (gc:closure code-ptr free-vars)))] + [else + (error 'forward/loc "Unknown tag: ~a" tag)])) + + +(define (object-size addr) + (define tag (heap-ref addr)) + (cond + [(equal? tag 'flat) 2] + [(equal? tag 'cons) 3] + [(equal? tag 'clos) + (let ([n-vars (+ addr 2)]) + (+ 3 n-vars))] + [(equal? tag 'forwarded) 2] + [else + (error 'object-size "Unknown tag: ~a" tag)])) + +(define (gc! . other-roots) + (swap-spaces!) + (heap-set! LOC:PTR 0) ; Reset the allocation pointer in the new semi-space + + ;; Forward all roots to the new semi-space + (for-each forward/root (get-root-set)) + (for-each forward/root other-roots) + + ;; Forward all objects reachable from the roots + (let loop ([scan (off)]) + (when (< scan (ptr)) + (forward/loc scan) + (loop (+ scan (object-size scan)))))) ;; gc:alloc-flat : flat-value -> address (define (gc:alloc-flat value)