diff options
author | Andy Wingo <wingo@pobox.com> | 2011-11-09 23:45:53 +0100 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2011-11-09 23:45:53 +0100 |
commit | fb135e12a473fd9a1612a59f904cfb90877fe775 (patch) | |
tree | 8a20716a5c5a62558d0ab859a71062a1cb56c617 /module | |
parent | acdf4fcc059df325f66698090359b3455725c865 (diff) |
when leaving a non-tail let, allow bound vals to be collected
* module/language/tree-il/compile-glil.scm (flatten-lambda-case): Clear
lexical stack slots at the end of a non-tail let, letrec, or fix.
Fixes http://debbugs.gnu.org/9900.
* test-suite/tests/gc.test ("gc"): Add test.
Diffstat (limited to 'module')
-rw-r--r-- | module/language/tree-il/compile-glil.scm | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/module/language/tree-il/compile-glil.scm b/module/language/tree-il/compile-glil.scm index 3daac7fca..de55026ab 100644 --- a/module/language/tree-il/compile-glil.scm +++ b/module/language/tree-il/compile-glil.scm @@ -237,6 +237,24 @@ (if (eq? context 'tail) (emit-code #f (make-glil-call 'return 1))))) + ;; After lexical binding forms in non-tail context, call this + ;; function to clear stack slots, allowing their previous values to + ;; be collected. + (define (clear-stack-slots context syms) + (case context + ((push drop) + (for-each (lambda (v) + (and=> + ;; Can be #f if the var is labels-allocated. + (hashq-ref allocation v) + (lambda (h) + (pmatch (hashq-ref h self) + ((#t _ . ,n) + (emit-code #f (make-glil-void)) + (emit-code #f (make-glil-lexical #t #f 'set n))) + (,loc (error "bad let var allocation" x loc)))))) + syms)))) + (record-case x ((<void>) (case context @@ -802,6 +820,7 @@ (,loc (error "bad let var allocation" x loc)))) (reverse gensyms)) (comp-tail body) + (clear-stack-slots context gensyms) (emit-code #f (make-glil-unbind))) ((<letrec> src in-order? names gensyms vals body) @@ -834,6 +853,7 @@ (,loc (error "bad letrec var allocation" x loc)))) (reverse gensyms)))) (comp-tail body) + (clear-stack-slots context gensyms) (emit-code #f (make-glil-unbind))) ((<fix> src names gensyms vals body) @@ -922,6 +942,7 @@ (comp-tail body) (if new-RA (emit-label new-RA)) + (clear-stack-slots context gensyms) (emit-code #f (make-glil-unbind)))) ((<let-values> src exp body) @@ -947,6 +968,7 @@ (,loc (error "bad let-values var allocation" x loc)))) (reverse gensyms)) (comp-tail body) + (clear-stack-slots context gensyms) (emit-code #f (make-glil-unbind)))))) ;; much trickier than i thought this would be, at first, due to the need |