Freeing memory is a pain. Need to decide on a protocol (who frees what?) Pollutes interfaces Errors hard to track down

Similar documents
Freeing memory is a pain. Need to decide on a protocol (who frees what?) Pollutes interfaces Errors hard to track down

Garbage Collection Basics

Reference Counting. Reference counting: a way to know whether a record has other users

Reference Counting. Reference counting: a way to know whether a record has other users

Programming Languages: Application and Interpretation

Programming Languages: Application and Interpretation

Scheme as implemented by Racket

How to Design Programs

Garbage Collection. Steven R. Bagley

A brief tour of history

Simple Garbage Collection and Fast Allocation Andrew W. Appel

Introduction to Typed Racket. The plan: Racket Crash Course Typed Racket and PL Racket Differences with the text Some PL Racket Examples

Garbage Collection. Hwansoo Han

Lecture 13: Garbage Collection

Runtime. The optimized program is ready to run What sorts of facilities are available at runtime

Procedural abstraction SICP Data abstractions. The universe of procedures forsqrt. Procedural abstraction example: sqrt

Lecture 15 Garbage Collection

Functional Programming. Pure Functional Languages

What goes inside when you declare a variable?

Class 6: Efficiency in Scheme

Tick: Concurrent GC in Apache Harmony

Quick announcement. Midterm date is Wednesday Oct 24, 11-12pm.

Acknowledgements These slides are based on Kathryn McKinley s slides on garbage collection as well as E Christopher Lewis s slides

CSE 413 Midterm, May 6, 2011 Sample Solution Page 1 of 8

Towards Lean 4: Sebastian Ullrich 1, Leonardo de Moura 2.

Scope, Functions, and Storage Management

Box-and-arrow Diagrams

Streams, Delayed Evaluation and a Normal Order Interpreter. CS 550 Programming Languages Jeremy Johnson

Garbage Collection Algorithms. Ganesh Bikshandi

HOT-Compilation: Garbage Collection

Test 1 Summer 2014 Multiple Choice. Write your answer to the LEFT of each problem. 5 points each 1. Preprocessor macros are associated with: A. C B.

Run-time Environments -Part 3

Lexical vs. Dynamic Scope

Managed runtimes & garbage collection. CSE 6341 Some slides by Kathryn McKinley

CS 360 Programming Languages Day 14 Closure Idioms

Racket: Modules, Contracts, Languages

Review. Partitioning: Divide heap, use different strategies per heap Generational GC: Partition by age Most objects die young

Run-time Environments - 3

Design Issues. Subroutines and Control Abstraction. Subroutines and Control Abstraction. CSC 4101: Programming Languages 1. Textbook, Chapter 8

Scheme. Functional Programming. Lambda Calculus. CSC 4101: Programming Languages 1. Textbook, Sections , 13.7

Run-Time Environments/Garbage Collection

Managed runtimes & garbage collection

Algorithms for Dynamic Memory Management (236780) Lecture 4. Lecturer: Erez Petrank

Compilers. 8. Run-time Support. Laszlo Böszörmenyi Compilers Run-time - 1

YOUR NAME PLEASE: *** SOLUTIONS ***

Typed Racket: Racket with Static Types

Project 2: Scheme Interpreter

CSE 413 Languages & Implementation. Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341)

CS 314 Principles of Programming Languages. Lecture 16

Rocking with Racket. Marc Burns Beatlight Inc

Structure and Interpretation of Computer Programs

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

This class is about understanding how programs work

Functional Programming. Pure Functional Languages

Module 10: General trees

Principles of Programming Languages

Programming Language Implementation

Programming Languages. Thunks, Laziness, Streams, Memoization. Adapted from Dan Grossman s PL class, U. of Washington

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Memory Management: The Details

Hard Real-Time Garbage Collection in Java Virtual Machines

A new Mono GC. Paolo Molaro October 25, 2006

Garbage Collection. Akim D le, Etienne Renault, Roland Levillain. May 15, CCMP2 Garbage Collection May 15, / 35

INF 212 ANALYSIS OF PROG. LANGS FUNCTION COMPOSITION. Instructors: Crista Lopes Copyright Instructors.

cs173: Programming Languages

CS 241 Honors Memory

Implementation Garbage Collection

CS 314 Principles of Programming Languages

Structure of Programming Languages Lecture 10

Common Misunderstandings from Exam 1 Material

BST Implementation. Data Structures. Lecture 4 Binary search trees (BST) Dr. Mahmoud Attia Sakr University of Ain Shams

Programming Languages. Function-Closure Idioms. Adapted from Dan Grossman's PL class, U. of Washington

(add1 3) 4 (check-expect (add1 3) 4)

6.172 Performance Engineering of Software Systems Spring Lecture 9. P after. Figure 1: A diagram of the stack (Image by MIT OpenCourseWare.

Harmony GC Source Code

Dynamic Data Structures (II)

CS61A Midterm 2 Review (v1.1)

Optimizing Scheme, part I

Principles of Programming Languages Topic: Functional Programming Professor L. Thorne McCarty Spring 2003

Scheme Quick Reference

Functional Programming. Pure Functional Programming

Lecture 15 Advanced Garbage Collection

Automatic Garbage Collection

CS 314 Principles of Programming Languages

Structure and Interpretation of Computer Programs

MEMORY MANAGEMENT HEAP, STACK AND GARBAGE COLLECTION

Heap Compression for Memory-Constrained Java

Objects CHAPTER 6. FIGURE 1. Concrete syntax for the P 3 subset of Python. (In addition to that of P 2.)

How do we mark reachable objects?

Virtual Memory Primitives for User Programs

Book keeping. Will post HW5 tonight. OK to work in pairs. Midterm review next Wednesday

CS577 Modern Language Processors. Spring 2018 Lecture Garbage Collection

Adding Machine Run 2

Reference Object Processing in On-The-Fly Garbage Collection

Mark-Sweep and Mark-Compact GC

regsim.scm ~/umb/cs450/ch5.base/ 1 11/11/13

06 A Low-Level Virtual Machine

Fall 2018 Discussion 8: October 24, 2018 Solutions. 1 Introduction. 2 Primitives

Compiler Construction

FrTime: A Language for Reactive Programs

Transcription:

Freeing memory is a pain Need to decide on a protocol (who frees what?) Pollutes interfaces Errors hard to track down 1

Freeing memory is a pain Need to decide on a protocol (who frees what?) Pollutes interfaces Errors hard to track down... but lets try an example anyway (fire isn t hot until it burns me) 2

Freeing memory is a pain ; (listof any) -> (listof any[no-cons]) (define (remove-pairs l) (cond [(empty? l) '()] [else (if (cons? (first l)) (remove-pairs (rest l)) (cons (first l) (remove-pairs (rest l))))])) 3

Freeing memory is a pain ; (listof any) -> (listof any[no-cons]) (define (remove-pairs l) (cond [(empty? l) '()] [else (begin (free! (first l)) (if (cons? (first l)) (remove-pairs (rest l)) (cons (first l) (remove-pairs (rest l)))))])) 4

Freeing memory is a pain ; (listof any) -> (listof any[no-cons]) (define (remove-pairs l) (cond [(empty? l) '()] [else (begin (free! (first l)) ; frees too much (if (cons? (first l)) (remove-pairs (rest l)) (cons (first l) (remove-pairs (rest l)))))])) 5

Freeing memory is a pain ; (listof any) -> (listof any[no-cons]) (define (remove-pairs l) (cond [(empty? l) '()] [else (begin (free! (first l)) ; frees too much (if (cons? (first l)) ;.. and too little (remove-pairs (rest l)) (cons (first l) (remove-pairs (rest l)))))])) 6

Freeing memory is a pain ; (listof any) -> (listof any[no-cons]) (define (remove-pairs l) (cond [(empty? l) '()] [else (begin (free! l) (if (cons? (first l)) (begin (free! (first l)) (remove-pairs (rest l))) (cons (first l) (remove-pairs (rest l)))))])) 7

Freeing memory is a pain ; (listof any) -> (listof any[no-cons]) (define (remove-pairs l) (cond [(empty? l) '()] [else (begin (free! l) ; frees too soon (if (cons? (first l)) (begin (free! (first l)) (remove-pairs (rest l))) (cons (first l) (remove-pairs (rest l)))))])) 8

Freeing memory is a pain ; (listof any) -> (listof any[no-cons]) (define (remove-pairs l) (cond [(empty? l) '()] [else (let ([ans (if (cons? (first l)) (begin (free! (first l)) (remove-pairs (rest l))) (cons (first l) (remove-pairs (rest l))))]) (free! l) ans)])) 9

Freeing memory is a pain ; (listof any) -> (listof any[no-cons]) (define (remove-pairs l) (cond [(empty? l) '()] [else (let ([ans (if (cons? (first l)) (begin (free! (first l)) (remove-pairs (rest l))) (cons (first l) (remove-pairs (rest l))))]) (free! l) ; broke tail recursion! ans)])) 10

Freeing memory is a pain ; (listof any) -> (listof any[no-cons]) (define (remove-pairs l) (begin0 (remove-pairs/real l) (cleanup l))) (define (cleanup l) (cond [(empty? l) (void)] [else (when (cons? (first l)) (free! (first l))) (let ([next (rest l)]) (free! l) (cleanup next))])) ; the original function (define (remove-pairs/real l)...) 11

Automatic storage management The PL has its own implementation of allocation; why not freeing too? When can we free an object? When we can guarantee that it won t be used again in the compuation 12

Automatic storage management The PL has its own implementation of allocation; why not freeing too? When can we free an object? When we can guarantee that it won t be used again in the compuation... when it isn t reachable; this is garbage collection 13

Garbage Collection Garbage collection: a way to know whether a record is live i.e., accessible 14

Garbage Collection Garbage collection: a way to know whether a record is live i.e., accessible Values on the stack & in registers are live (the roots) A record referenced by a live record is also live A program can only possibly use live records, because there is no way to get to other records 15

Garbage Collection Garbage collection: a way to know whether a record is live i.e., accessible Values on the stack & in registers are live (the roots) A record referenced by a live record is also live A program can only possibly use live records, because there is no way to get to other records A garbage collector frees all records that are not live Allocate until we run out of memory, then run a garbage collector to get more space 16

Time to write a garbage collector Two new languages: #lang plai/mutator for writing progams to be collected, and #lang plai/collector for writing collectors Collector interface, see section 2.2 of the PLAI docs (search for init-alloctor) 17

Rules of the game All values are allocated (we have no type information!) Atomic values include numbers (a lie), symbols (a less bad lie), booleans, and the empty list Compound values include pairs (we do ourselves) and closures (we get help) 18

A non-collecting collector Put the allocation pointer at address 0 Allocate all constants in the heap, tag them with 'flat Allocate all pairs in the heap, tag them with 'pair 19

A non-collecting collector #lang plai/collector (define (init-allocator) (heap-set! 0 1)) (define (alloc n) (let ([addr (heap-ref 0)]) (heap-set! 0 (+ addr n)) addr)) 20

A non-collecting collector, cotd (define (gc:flat? addr) (equal? (heap-ref addr) 'flat)) (define (gc:alloc-flat x) (let ([addr (alloc 2)]) (heap-set! addr 'flat) (heap-set! (+ addr 1) x) addr)) (define (gc:deref addr) (if (gc:flat? addr) (heap-ref (+ addr 1)) (error 'gc:deref "expected a flat value, got addr ~s" addr))) 21

A non-collecting collector, cotd (define (gc:cons hd tl) (let ([addr (alloc 3)]) (heap-set! addr 'cons) (heap-set! (+ addr 1) hd) (heap-set! (+ addr 2) tl) addr)) (define (gc:cons? pr) (equal? (heap-ref pr) 'cons)) 22

A non-collecting collector, cotd (define (gc:first addr) (chk-pair addr 'gc:first) (heap-ref (+ addr 1))) (define (gc:rest addr) (chk-pair addr 'gc:rest) (heap-ref (+ addr 2))) (define (chk-pair pr who) (unless (gc:cons? pr) (error who "expected a pair, got addr ~a" pr))) 23

A non-collecting collector, cotd (define (gc:set-first! addr nv) (chk-pair addr 'gc:set-first!) (heap-set! (+ addr 1) nv)) (define (gc:set-rest! addr nv) (chk-pair addr 'gc:set-rest!) (heap-set! (+ addr 2) nv)) 24

Testing a collector We can use with-heap to test a collector. The expression (with-heap h-expr body-exprs...) expects h-expr to evaluate to a vector and then it uses that vector as the memory that heap-ref and heap-set! refer to while evaluating the body-exprs. 25

Testing our non-collecting collector (let ([h (vector 'x 'x 'x 'x 'x)]) (test (with-heap h (init-allocator) (gc:alloc-flat #f) h) (vector 3 'flat #f 'x 'x))) (let ([h (vector 'x 'x 'x 'x 'x 'x 'x 'x 'x)]) (test (with-heap h (init-allocator) (gc:cons (gc:alloc-flat #f) (gc:alloc-flat #t)) h) (vector 8 'flat #f 'flat #t 'cons 1 3 'x))) ; (Of course, this is not enough testing.) 26

Random mutators #lang racket (require plai/random-mutator) (save-random-mutator "tmp.rkt" "collector.rkt") #lang plai/mutator (allocator-setup "collector.rkt" 200) (import-primitives symbol=?) (define (build-one) (let* ((x0 empty) (x1 (cons #f x0)) (x2 empty) (x3 (cons #f x0)) (x4 (lambda (x) (if (= x 0) x2 (if (= x 1) x1 (if (= x 2) x1 (if (= x 3) x0 x0)))))) (x5-1) (x6 'x) (x7 (lambda (x) (if (= x 0) x6 (if (= x 1) x1 (if (= x 2) x4 (if (= x 3) x4 (if (= x 4) x6 (if (= x 5) x3 (if (= x 6) x2 (if (= x 7) x3 x4))))))))))) (set-first! x1 x2) (set-first! x3 x6) x7)) (define (traverse-one x7) (empty? (rest (x7 1)))) (define (trigger-gc n) (if (zero? n) 0 (begin (cons n n) (trigger-gc (- n 1))))) (define (loop i) (if (zero? i) 'passed (let ((obj (build-one))) (trigger-gc 200) (if (traverse-one obj) (loop (- i 1)) 'failed)))) (loop 200) 27

Random mutators #lang racket (require plai/random-mutator) (save-random-mutator "tmp.rkt" "collector.rkt") #lang plai/mutator (allocator-setup "collector.rkt" 200) (import-primitives symbol=?) (define (build-one) (let* ((x0 empty)) x0)) (define (traverse-one x0) (empty? x0)) (define (trigger-gc n) (if (zero? n) 0 (begin (cons n n) (trigger-gc (- n 1))))) (define (loop i) (if (zero? i) 'passed (let ((obj (build-one))) (trigger-gc 200) (if (traverse-one obj) (loop (- i 1)) 'failed)))) (loop 200) 28

Random mutators #lang racket (require plai/random-mutator) (save-random-mutator "tmp.rkt" "collector.rkt") #lang plai/mutator (allocator-setup "collector.rkt" 200) (import-primitives symbol=?) (define (build-one) (let* ((x0 'y) (x1 (cons #f #f)) (x2 'y) (x3 (lambda (x) (if (= x 0) x0 (if (= x 1) x2 (if (= x 2) x2 x0))))) (x4 (lambda (x) (if (= x 0) x1 (if (= x 1) x0 (if (= x 2) x1 (if (= x 3) x1 (if (= x 4) x2 (if (= x 5) x1 (if (= x 6) x3 (if (= x 7) x3 (if (= x 8) x0 x1))))))))))) (x5 (cons x0 x4))) (set-first! x1 x3) (set-rest! x1 x5) x3)) (define (traverse-one x3) (symbol=? 'y (x3 0))) (define (trigger-gc n) (if (zero? n) 0 (begin (cons n n) (trigger-gc (- n 1))))) (define (loop i) (if (zero? i) 'passed (let ((obj (build-one))) (trigger-gc 200) (if (traverse-one obj) (loop (- i 1)) 'failed)))) (loop 200) 29