Heap liveness and its usage in automatic memory management Ran Shaham Elliot Kolodner Mooly Sagiv ISMM’02 Unpublished TVLA.

Slides:



Advertisements
Similar presentations
Chapter 22 Implementing lists: linked implementations.
Advertisements

Garbage collection David Walker CS 320. Where are we? Last time: A survey of common garbage collection techniques –Manual memory management –Reference.
Introduction to Memory Management. 2 General Structure of Run-Time Memory.
1 Write Barrier Elision for Concurrent Garbage Collectors Martin T. Vechev Cambridge University David F. Bacon IBM T.J.Watson Research Center.
Automatic Memory Management Noam Rinetzky Schreiber 123A /seminar/seminar1415a.html.
Context-Sensitive Interprocedural Points-to Analysis in the Presence of Function Pointers Presentation by Patrick Kaleem Justin.
Compilation 2011 Static Analysis Johnni Winther Michael I. Schwartzbach Aarhus University.
Topic 10 Java Memory Management. 1-2 Memory Allocation in Java When a program is being executed, separate areas of memory are allocated for each class.
Dynamic Memory Allocation I Topics Basic representation and alignment (mainly for static memory allocation, main concepts carry over to dynamic memory.
Pointer Analysis – Part I Mayur Naik Intel Research, Berkeley CS294 Lecture March 17, 2009.
Demand-driven Alias Analysis Implementation Based on Open64 Xiaomi An
Garbage Collection What is garbage and how can we deal with it?
Memory Management & Method Calls in Java Program Execution © Allan C. Milne v
Garbage Collection CSCI 2720 Spring Static vs. Dynamic Allocation Early versions of Fortran –All memory was static C –Mix of static and dynamic.
CS 326 Programming Languages, Concepts and Implementation Instructor: Mircea Nicolescu Lecture 18.
Chapter 8 Runtime Support. How program structures are implemented in a computer memory? The evolution of programming language design has led to the creation.
Establishing Local Temporal Heap Safety Properties with Applications to Compile-Time Memory Management Ran Shaham Eran Yahav Elliot Kolodner Mooly Sagiv.
Run-Time Storage Organization
Compile-Time Deallocation of Individual Objects Sigmund Cherem and Radu Rugina International Symposium on Memory Management June, 2006.
Age-Oriented Concurrent Garbage Collection Harel Paz, Erez Petrank – Technion, Israel Steve Blackburn – ANU, Australia April 05 Compiler Construction Scotland.
Stacks. 2 Outline and Reading The Stack ADT (§2.1.1) Applications of Stacks (§2.1.1) Array-based implementation (§2.1.1) Growable array-based stack (§1.5)
Overview of program analysis Mooly Sagiv html://
Reference Types. 2 Objectives Introduce reference types –class –array Discuss details of use –declaration –allocation –assignment –null –parameter –aggregation.
1 Run time vs. Compile time The compiler must generate code to handle issues that arise at run time Representation of various data types Procedure linkage.
Overview of program analysis Mooly Sagiv html://
Ch 4. Memory Management Timothy Budd Oregon State University.
A Portable Virtual Machine for Program Debugging and Directing Camil Demetrescu University of Rome “La Sapienza” Irene Finocchi University of Rome “Tor.
Fast, Effective Code Generation in a Just-In-Time Java Compiler Rejin P. James & Roshan C. Subudhi CSE Department USC, Columbia.
 2007 Pearson Education, Inc. All rights reserved C Data Structures.
Lecture 10 : Introduction to Java Virtual Machine
1 Comp 104: Operating Systems Concepts Java Development and Run-Time Store Organisation.
Compiler Construction
Stephen P. Carl - CS 2421 Recursion Reading : Chapter 4.
Chapter 5: Programming Languages and Constructs by Ravi Sethi Activation Records Dolores Zage.
CSC 212 Stacks & Queues. Announcement Many programs not compiled before submission  Several could not be compiled  Several others not tested with javadoc.
Computer Science and Software Engineering University of Wisconsin - Platteville 2. Pointer Yan Shi CS/SE2630 Lecture Notes.
© 2004 Goodrich, Tamassia Stacks. © 2004 Goodrich, Tamassia Stacks2 Abstract Data Types (ADTs) An abstract data type (ADT) is an abstraction of a data.
Conrad Benham Java Opcode and Runtime Data Analysis By: Conrad Benham Supervisor: Professor Arthur Sale.
Chameleon Automatic Selection of Collections Ohad Shacham Martin VechevEran Yahav Tel Aviv University IBM T.J. Watson Research Center Presented by: Yingyi.
30 May Stacks (5.1) CSE 2011 Winter Stacks2 Abstract Data Types (ADTs) An abstract data type (ADT) is an abstraction of a data structure An.
Advanced Java Programming CS 537 – Data Structures and Algorithms.
Finding Your Cronies: Static Analysis for Dynamic Object Colocation Samuel Z. Guyer Kathryn S. McKinley T H E U N I V E R S I T Y O F T E X A S A T A U.
Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. C H A P T E R F I V E Memory Management.
Lists II. List ADT When using an array-based implementation of the List ADT we encounter two problems; 1. Overflow 2. Wasted Space These limitations are.
RUN-Time Organization Compiler phase— Before writing a code generator, we must decide how to marshal the resources of the target machine (instructions,
Symbolic Execution with Abstract Subsumption Checking Saswat Anand College of Computing, Georgia Institute of Technology Corina Păsăreanu QSS, NASA Ames.
Computer Organization and Design Pointers, Arrays and Strings in C Montek Singh Sep 18, 2015 Lab 5 supplement.
GARBAGE COLLECTION IN AN UNCOOPERATIVE ENVIRONMENT Hans-Juergen Boehm Computer Science Dept. Rice University, Houston Mark Wieser Xerox Corporation, Palo.
CSE 374 Programming Concepts & Tools Hal Perkins Fall 2015 Lecture 10 – C: the heap and manual memory management.
More Examples of Abstract Interpretation Register Allocation.
Spring, 2011 –– Computational Thinking – Dennis Kafura – CS 2984 Data Structures Mapping complex structures to linear memory.
LECTURE 13 Names, Scopes, and Bindings: Memory Management Schemes.
® July 21, 2004GC Summer School1 Cycles to Recycle: Copy GC Without Stopping the World The Sapphire Collector Richard L. Hudson J. Eliot B. Moss Originally.
CS412/413 Introduction to Compilers and Translators April 21, 1999 Lecture 30: Garbage collection.
GC Assertions: Using the Garbage Collector To Check Heap Properties Samuel Z. Guyer Tufts University Edward Aftandilian Tufts University.
Eliminating External Fragmentation in a Non-Moving Garbage Collector for Java Author: Fridtjof Siebert, CASES 2000 Michael Sallas Object-Oriented Languages.
Design issues for Object-Oriented Languages
Garbage Collection What is garbage and how can we deal with it?
YAHMD - Yet Another Heap Memory Debugger
12 C Data Structures.
Cork: Dynamic Memory Leak Detection with Garbage Collection
Compositional Pointer and Escape Analysis for Java Programs
Stacks.
Java Review: Reference Types
Storage.
Strategies for automatic memory management
Closure Representations in Higher-Order Programming Languages
UNIT V Run Time Environments.
Created By: Asst. Prof. Ashish Shah, J.M.Patel College, Goregoan West
Garbage Collection What is garbage and how can we deal with it?
Presentation transcript:

Heap liveness and its usage in automatic memory management Ran Shaham Elliot Kolodner Mooly Sagiv ISMM’02 Unpublished TVLA inside

Motivation An object could be collected once it is no longer needed –Yet, run-time garbage collectors (RTGCs) are typically based on reachability Profiling tools can detect when objects are needed The compiler can: –Statically identify a subset of unneeded objects –Issue a free instruction (compile-time Garbage Collection) –Issue a warning when a potentially needed object is reclaimed –Inform run-time garbage collector that a reference to an object is not further used

A Pathological C Program a = malloc(…) ; b = a; free (a); c = malloc (…); if (b == c) printf(“unexpected equality”);

Inefficient Java Class public Class Stack { private Object stack[]; private int top; public Stack(int len) { stack = new Object[len]; top = 0; } public synchronized Object pop() { top= top-1; return stack[top]; } public synchronized void push(Object o) { stack[top]=o; top= top+1; } public synchronized void print() { for (int i=0; i<top; i++) { System.out.println(stack[i]); } GC does not reclaim the memory stack[top+1]

Needed Location p p’ l is needed a reference to l is used l is allocated

Needed Reference Expression p p’ e is needed a reference to l is used e references l e is not needed  free(e) is valid l is allocated

A Pathological C Program a = malloc(…) ; b = a; free (a); c = malloc (…); if (b == c) printf(“unexpected equality”); a is needed

Location Liveness p p’ l is live l is not assigned l is used

Reference Expression Liveness p p’ e is live e denotes a location l l is not assigned l is used Generalizes liveness of program variables when l is &x

Inefficient Java Class public Class Stack { private Object stack[]; private int top; public Stack(int len) { stack = new Object[len]; top = 0; } public synchronized Object pop() { top= top-1; return stack[top]; } public synchronized void push(Object o) { stack[top]=o; top= top+1; } public synchronized void print() { for (int i=0; i<top; i++) { System.out.println(stack[i]); } stack[top+1] is not live

Typical GC Limits class Node { Node left, right; int data; } class C { void main(…) { Node root = createTree(); processTree(root.right); } root

Typical GC Limits class Node { Node left, right; int data; } class C { void main(…) { Node root = createTree(); processTree(root.right); } root

Typical GC Limits class Node { Node left, right; int data; } class C { void main(…) { Node root = createTree(); processTree(root.right); } root

Liveness Analysis Aids GC class Node { Node left, right; int data; } class C { void main(…) { Node root = createTree(); processTree(root.right); } root root.right is live, root.left is dead

Liveness Analysis Aids GC class Node { Node left, right; int data; } class C { void main(…) { Node root = createTree(); processTree(root.right); } root root.right is live, root.left is dead

Liveness Analysis Aids GC class Node { Node left, right; int data; } class C { void main(…) { Node root = createTree(); processTree(root.right); } root root.right is live, root.left is dead

Liveness Analysis Aids GC class Node { Node left, right; int data; } class C { void main(…) { Node root = createTree(); processTree(root.right); } root root.right is live, root.left is dead

Typical GC Limits Program Variables a b c d e f

Outline Dynamic liveness measurements –Complete location liveness –Assign-null interface Static analysis algorithms –(Exact) assign null (improve GC) –(Exact) free (CTGC)

Dynamic Liveness Measurements Estimating the potential of static analysis –Find upper bounds on expected savings Can be used in as an assistant tool Liveness information kinds –Stack reference liveness –Global reference liveness –Heap reference liveness

Main Results Dynamic measurements for 10 benchmarks Shallow information  Small Potential –local variables 2% –global variables 5% –local + global 9% Deep information  Larger Potential –heap liveness 39% complete location liveness 15% assign-null interface

Dynamic measurements –Implemented via an instrumented JVM Complete location liveness measurements –Single-run algorithm Assign-null liveness interface –Determines the liveness of expressions –Assign null to dead reference expressions –Requires two runs of the program

Complete Liveness Measurements An Observation The last use of the references to an object determines the time an object could be collected assuming liveness information

Heap Liveness Example I Stack y z g Static x f f2f2 f1f1 f f Heap L = t … use z.f f Heap L  = t

Heap Liveness Example I Stack y z g Static x f f2f2 f1f1 f f Heap L = t+2 … use y.f2 f Heap L = t  = t+2

Heap Liveness Example II Stack y z g Static x f f2f2 f1f1 f f Stack R = t’’ f Stack R = Directly stack reachable (computed during GC) Collection time = max(t’, t’’) Collection time(obj) = max(Heap L (obj), Stack R (obj), Static R (obj), Other R (obj))  = t’’ Heap L = t’

Stack Liveness Example I Stack y z g Static x f f2f2 f1f1 f f Stack L = t … use z [Current Time = t] f Stack L

Stack Liveness Example I Stack y z g Static x f f2f2 f1f1 f f Stack L = t f … use y [Current Time = t+2] Stack L = t+2

Stack Liveness Example I Stack y z g Static x f f2f2 f1f1 f f Stack L = t f Stack L* = path starting with a live stack root (computed during GC trace phase) Stack L = t+2

Stack Liveness Example I Stack y z g Static x f f2f2 f1f1 f f Stack L* = t f Stack L* = path starting with a live stack root (computed during GC trace phase) Stack L* = t+2

Stack Liveness Example II Stack y z g Static x f f2f2 f1f1 f f Stack L* = t f Static R* = path starting with a static root (computed during GC trace phase) Stack L* = t+2 Static R* = t’ Stack L* = t+2 Static R* = t’ Collection time = max(t+2, t’) Collection time(obj) = max(Stack L* (obj), Static R* (obj), Other R* (obj))

PropertyIntended Meaning heap L (obj)obj is referenced by a live heap reference at time heap L (obj) stack L (obj)obj is referenced by a live stack root at time stack L (obj) stack L* (obj)obj is reachable along a path starting from a live stack root at time stack L* (obj) stack R (obj)obj is referenced by a stack root at time stack R (obj) stack R* (obj)obj is reachable along a path starting from a stack root at time stack R* (obj) static L (obj)obj is referenced by a live static root at time static L (obj) static L* (obj)obj is reachable along a path starting from a live static root at time static l* (obj) static R (obj)obj is referenced by a static root at time static R (obj) static R* (obj)obj is reachable along a path starting from a static root at time static R* (obj) other R (obj)obj is referenced by an other root at time other R (obj) other R* (obj)obj is reachable along a path starting from an other root at time other R* (obj)

Complete Liveness Summary Mutator –Tracks the last use of references to an object Collector –Propagation needed for stack/static liveness –Propagates reachability information –Propagates path liveness Object Collection/Program Termination –Maximum of liveness/reachability properties of an object –Depends on liveness scheme (heap liveness etc.)

Experimental Results Instrumented Sun’s classic JVM (1.2) 10 benchmarks (5 SPECjvm) Time is measured bytes allocated by the mutator so far in program Total space savings (integral) Maximum heap size savings (footprint)

Potential Savings – Total Space

Restricted GC Interface GC Interface –Should be simple/effective/efficient –Feasible heap liveness representation Assign null to dead heap references –Simple –Effective? Partially answered by our experiments –Efficient? Will be answered by static analysis

Null Assignable Program Points Normalized statements (Java Bytecode) –Manipulate at most one heap reference x = y.f is null assignable –Could be followed by y.f = null Dynamic algorithm –First run Determine null assignable program points –Assume all program points are null assignable –Detect non-null-assignable program points during the run –Second run Assign null in null assignable program points

Doubly-Linked List Example – First Run x n p dd n p dd // processing list elements in pairs pt 1 : y = x.n; // x.n = null; x = null; while (y != null) { pt 2 : t = y.p; // y.p = null; pt 3 : d1 = t.d; // t.d = null pt 4 : d2 = y.d; // y.d = null process(d1, d2); pt 5 : t = y.n; // y.n = null; y = t; }

Doubly-Linked List Example – First Run x n p dd n p dd [pt 1 ] // processing list elements in pairs pt 1 : y = x.n; // x.n = null; x = null; while (y != null) { pt 2 : t = y.p; // y.p = null; pt 3 : d1 = t.d; // t.d = null pt 4 : d2 = y.d; // y.d = null process(d1, d2); pt 5 : t = y.n; // y.n = null; y = t; } y

Doubly-Linked List Example – First Run n p dd n p dd y t [pt 2 ] [pt 1 ] // processing list elements in pairs pt 1 : y = x.n; // x.n = null; x = null; while (y != null) { pt 2 : t = y.p; // y.p = null; pt 3 : d1 = t.d; // t.d = null pt 4 : d2 = y.d; // y.d = null process(d1, d2); pt 5 : t = y.n; // y.n = null; y = t; }

Doubly-Linked List Example – First Run n p dd n p dd y t [pt 2 ] [pt 3 ] d1 [pt 1 ] // processing list elements in pairs pt 1 : y = x.n; // x.n = null; x = null; while (y != null) { pt 2 : t = y.p; // y.p = null; pt 3 : d1 = t.d; // t.d = null pt 4 : d2 = y.d; // y.d = null process(d1, d2); pt 5 : t = y.n; // y.n = null; y = t; }

Doubly-Linked List Example – First Run n p dd n p dd y t [pt 2 ] [pt 3 ] d1 [pt 4 ] d2 [pt 1 ] // processing list elements in pairs pt 1 : y = x.n; // x.n = null; x = null; while (y != null) { pt 2 : t = y.p; // y.p = null; pt 3 : d1 = t.d; // t.d = null pt 4 : d2 = y.d; // y.d = null process(d1, d2); pt 5 : t = y.n; // y.n = null; y = t; }

Doubly-Linked List Example – First Run n p dd n p dd y t [pt 2 ] [pt 3 ] d1 [pt 4 ] d2 [pt 5 ] [pt 1 ] // processing list elements in pairs pt 1 : y = x.n; // x.n = null; x = null; while (y != null) { pt 2 : t = y.p; // y.p = null; pt 3 : d1 = t.d; // t.d = null pt 4 : d2 = y.d; // y.d = null process(d1, d2); pt 5 : t = y.n; // y.n = null; y = t; }

Doubly-Linked List Example – First Run n p dd n p dd t y [pt 2 ] [pt 3 ] d1 [pt 4 ] d2 [pt 5 ] [pt 2 ] [pt 1 ] // processing list elements in pairs pt 1 : y = x.n; // x.n = null; x = null; while (y != null) { pt 2 : t = y.p; // y.p = null; pt 3 : d1 = t.d; // t.d = null pt 4 : d2 = y.d; // y.d = null process(d1, d2); pt 5 : t = y.n; // y.n = null; y = t; }

[pt 4 ] Doubly-Linked List Example – First Run n p dd n p dd t y [pt 2 ] [pt 3 ] d1 [pt 3 ] d2 [pt 5 ] [pt 1 ] // processing list elements in pairs pt 1 : y = x.n; // x.n = null; x = null; while (y != null) { pt 2 : t = y.p; // y.p = null; pt 3 : d1 = t.d; // t.d = null pt 4 : d2 = y.d; // y.d = null process(d1, d2); pt 5 : t = y.n; // y.n = null; y = t; }

Doubly-Linked List Example – First Run n p dd n p dd [pt 2 ] [pt 3 ] d2 [pt 3 ] d1 [pt 5 ] [pt 3 ] [pt 1 ] [pt 3 ] // processing list elements in pairs pt 1 : y = x.n; // x.n = null; x = null; while (y != null) { pt 2 : t = y.p; // y.p = null; pt 3 : d1 = t.d; // t.d = null pt 4 : d2 = y.d; process(d1, d2); pt 5 : t = y.n; // y.n = null; y = t; }

Doubly-Linked List Example - Second Run x n p dd n p dd // processing list elements in pairs pt 1 : y = x.n; x.n = null; x = null; while (y != null) { pt 2 : t = y.p; y.p = null; pt 3 : d1 = t.d; t.d = null pt 4 : d2 = y.d; process(d1, d2); pt 5 : t = y.n; y.n = null; y = t; }

n p dd n p d d ty // processing list elements in pairs pt 1 : y = x.n; x.n = null; x = null; while (y != null) { pt 2 : t = y.p; y.p = null; pt 3 : d1 = t.d; t.d = null pt 4 : d2 = y.d; process(d1, d2); pt 5 : t = y.n; y.n = null; y = t; } Doubly-Linked List Example - Second Run d1 d2

// processing list elements in pairs pt 1 : y = x.n; x.n = null; x = null; while (y != null) { pt 2 : t = y.p; y.p = null; pt 3 : d1 = t.d; t.d = null pt 4 : d2 = y.d; process(d1, d2); pt 5 : t = y.n; y.n = null; y = t; } Doubly-Linked List Example - Second Run d n p d d ty d1 d2

15% average savings for context = 2 –11% assigning null to instance fields –10% assigning null to array elements Results are valid across runs –Detecting null assignable program points on a second input –Running the program with the first input –null assignable program points are those detected for both inputs

Related Work On the Usefulness of Liveness for Garbage Collection and Leak Detection [HDH01] –Does not handle heap liveness –Algorithm requires two runs First run: record uses and defs Analyze log backwards for liveness information Second run: use liveness results Garbage Collection and Local Variable Type-Precision and Liveness in Java Virtual Machines [ADM98] –Stack liveness static analysis –Actual trends match our upper bounds On the Effectiveness of GC in Java [SKS00] –Drag information Slightly larger potential than heap liveness information Not clear how to automate space savings HUP tool (PLDI’01 + M. Pan)

Dynamic liveness measurements - Conclusion Liveness Information has large potential Assign null savings “achievable” by static analysis Stack liveness information –Small potential Stack+static liveness information –Medium potential Heap liveness information –Is feasible Recording history on heap is a powerful mechanism –Larger potential Depends on static analysis precision Depends on GC interface

Static Analysis Combine history with shape analysis –a-La- Horwitz, Pfeiffer, and Reps 1989 Assign null –Assign null to a dead reference expression –GC exploits information Free –free an unneeded object

Assign Null Analysis –Insert “x.fld = null” after statements in which the expression x.fld becomes dead –Limitations Only one reference is assigned null All the paths to the statement must agree –Detects last-use –Technically llastu[pt,x.fld](v) – The last use of the location denoted by x.fld occurs at pt null[pt,x.fld]() –It is safe to insert “x.fld = null” after pt

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n n null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x,y n n null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x,y n n null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x,y n llastu[pt 3,y.n] n n t null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n llastu[pt 3,y.n] n n y,t null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n llastu[pt 3,y.n] n n y,t null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n llastu[pt 3,y.n] n n y n t null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n llastu[pt 3,y.n] n n n y,t null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n llastu[pt 3,y.n] n n n y,t null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n llastu[pt 3,y.n] n n n y n t null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n n llastu[pt 3,y.n] n n y,t n null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n n llastu[pt 3,y.n] n n y,t n

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n llastu[pt 3,y.n] n n n y n t n null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n llastu[pt 3,y.n] n n n y,t n null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n llastu[pt 3,y.n] n n n y,t n null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n llastu[pt 3,y.n] n y n null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n llastu[pt 3,y.n] n null[pt 3,y.n]

Assign Null Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n llastu[pt 3,y.n] n null[pt 3,y.n]

Static Reachability Information + Static Liveness Information CT garbage detection Issue “free(e)” for unneeded e Compile-Time Garbage Collection

Exact Free Analysis –Insert free(x) at program points when the x becomes unneeded Only one location is freed All the paths to the statement must agree on the garbage –History predicates lastu[pt,x](v) – the last use of the location pointed-to by x occurs unneeded [pt,x]() –“free(x)” is safe after pt

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n n unneeded[pt 1,x] unneeded[pt 2,y] unneeded[pt 3,y] unneeded[pt 4,t]

Exact unneeded Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x,y n n unneeded[pt 1,x] unneeded[pt 2,y] unneeded[pt 3,y] unneeded[pt 4,t] lastu[pt 1,x]

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x,y n n unneeded[pt 2,y] unneeded[pt 3,y] unneeded[pt 4,t] lastu[pt 2,y]

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x,y n unneeded[pt 3,y] unneeded[pt 4,t] lastu[pt 3,y] n n t

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n unneeded[pt 3,y] unneeded[pt 4,t] lastu[pt 3,y] n n y,t lastu[pt 4,t]

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n unneeded[pt 3,y] lastu[pt 3,y] n n y,t lastu[pt 2,y]

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n unneeded[pt 3,y] lastu[pt 3,y] n n y n t

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n unneeded[pt 3,y] lastu[pt 3,y] n n n lastu[pt 4,t] y,t

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n unneeded[pt 3,y] lastu[pt 3,y] n n n lastu[pt 2,y] y,t

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n unneeded[pt 3,y] lastu[pt 3,y] n n n y n t

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x unneeded[pt 3,y] n n lastu[pt 3,y] n n y,t lastu[pt 4,t] n

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x unneeded[pt 3,y] n n lastu[pt 3,y] n n y,t lastu[pt 2,y] n

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n unneeded[pt 3,y] lastu[pt 3,y] n n n y n t n

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n unneeded[pt 3,y] lastu[pt 3,y] n n n y,t n lastu[pt 4,t]

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n unneeded[pt 3,y] lastu[pt 3,y] n n n y,t n lastu[pt 2,y]

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n unneeded[pt 3,y] lastu[pt 3,y] n n y

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n unneeded[pt 3,y] lastu[pt 3,y] n

Exact Free Example // traversing list elements pt 1 : y = x; pt 2 : while (y != null) { pt 3 : t = y.n; pt 4 : y = t; } x n unneeded[pt 3,y] lastu[pt 3,y] n

Preliminary Conclusions Heap Liveness is useful Can be dynamically computed for large programs More data is needed to confirm scalability of static analysis Recording local history is a powerful tool –Refines the abstraction