JPure: a Modular Purity System for Java - PowerPoint PPT Presentation

1 / 40
About This Presentation
Title:

JPure: a Modular Purity System for Java

Description:

JPure: a Modular Purity System for Java David J. Pearce Victoria University of Wellington New Zealand – PowerPoint PPT presentation

Number of Views:76
Avg rating:3.0/5.0
Slides: 41
Provided by: JamesN167
Category:

less

Transcript and Presenter's Notes

Title: JPure: a Modular Purity System for Java


1
JPure a Modular Purity System for Java
  • David J. Pearce
  • Victoria University of Wellington
  • New Zealand

2
Introduction
Definition A method is considered pure if it
does not assign (directly of indirectly) to any
field or array cell that existed before it was
called.
int sum(int items) int r 0 for(int
v items) r v return r
boolean isSorted(ListltIntegergt items) int
last Integer.MIN_VALUE for(Integer v
items) if(last gt v) return false
last v return true
3
Typical Previous Purity Systems
Pointer Analysis
Purity Inference
Annotated Source
Java Source
?
Annotated Bytecode
  • Pointer Analysis feeds Purity Inference
  • Pointer Analysis typically whole-program
  • Inferred annotations cannot be checked easily
  • i.e. without regeneration pointer information

4
Modular Purity System
Purity Inference
Java Compiler
Annotated Source
Java Source
Purity Checker
Annotated Bytecode
  • Purity Inference
  • Generates annotations via interprocedural
    analysis
  • Generated annotations are modularly checkable
  • Purity Checker
  • Verifies annotations via intraprocedural analysis
  • Integrates easily with Java Bytecode Verification

5
Simple (Modular) Approach
  • Pure Methods
  • Cannot contain field assignments
  • Can only call methods marked _at_Pure
  • Only pure methods can override pure methods

6
Simple (Modular) Approach
  • Pure Methods
  • Cannot contain field assignments
  • Can only call methods marked _at_Pure
  • Only pure methods can override pure methods

7
Simple (Modular) Approach
Parent private int f _at_Pure void method()f1
  • Pure Methods
  • Cannot contain field assignments
  • Can only call methods marked _at_Pure
  • Only pure methods can override pure methods

8
Simple (Modular) Approach
  • Pure Methods
  • Cannot contain field assignments
  • Can only call methods marked _at_Pure
  • Only pure methods can override pure methods

9
Simple (Modular) Approach
  • Pure Methods
  • Cannot contain field assignments
  • Can only call methods marked _at_Pure
  • Only pure methods can override pure methods

10
Problems
public class Test private ListltStringgt
items _at_Pure boolean has(String s)
for(String i items) if(s i)
return true return false
public class AbstractStringBuilder private
char data private int count // number of
items used public AbstractStringBuilder
append(String s) s.getChars(0,
s.length(), data, count) _at_Pure String
f(String x) return x hello
11
Problems
public class Test private ListltStringgt
items _at_Pure boolean has(String s)
for(String i items) if(s i)
return true return false
public class AbstractStringBuilder private
char data private int count // number of
items used public AbstractStringBuilder
append(String s) s.getChars(0,
s.length(), data, count) _at_Pure String
f(String x) return x hello
12
Problems
public class Test private ListltStringgt
items _at_Pure boolean has(String s)
for(String i items) if(s i)
return true return false
public class AbstractStringBuilder private
char data private int count // number of
items used public AbstractStringBuilder
append(String s) s.getChars(0,
s.length(), data, count) _at_Pure String
f(String x) return x hello
13
Problems
public class Test private ListltStringgt
items _at_Pure boolean has(String s)
for(String i items) if(s i)
return true return false
public class AbstractStringBuilder private
char data private int count // number of
items used public AbstractStringBuilder
append(String s) s.getChars(0,
s.length(), data, count) _at_Pure String
f(String x) return x hello
14
Introducing JPure!
interface Collection _at_Fresh Object
iterator() interface Iterator _at_Pure
boolean hasNext() _at_Local Object
next() class Test ListltStringgt items
_at_Pure boolean has(String s) for(String i
items) if(s i) return true
return false
15
Introducing JPure!
Indicates iterator() returns fresh object
interface Collection _at_Fresh Object
iterator() interface Iterator _at_Pure
boolean hasNext() _at_Local Object
next() class Test ListltStringgt items
_at_Pure boolean has(String s) for(String i
items) if(s i) return true
return false
16
Introducing JPure!
Indicates iterator() returns fresh object
interface Collection _at_Fresh Object
iterator() interface Iterator _at_Pure
boolean hasNext() _at_Local Object
next() class Test ListltStringgt items
_at_Pure boolean has(String s) for(String i
items) if(s i) return true
return false
Indicates next() only modifies local state
17
Introducing JPure!
Indicates iterator() returns fresh object
interface Collection _at_Fresh Object
iterator() interface Iterator _at_Pure
boolean hasNext() _at_Local Object
next() class Test ListltStringgt items
_at_Pure boolean has(String s) for(String i
items) if(s i) return true
return false
Indicates next() only modifies local state
18
Introducing JPure!
Indicates iterator() returns fresh object
interface Collection _at_Fresh Object
iterator() interface Iterator _at_Pure
boolean hasNext() _at_Local Object
next() class Test ListltStringgt items
_at_Pure boolean has(String s) for(String i
items) if(s i) return true
return false
Indicates next() only modifies local state
_at_Pure boolean has(String s) Iterator tmp
tmp items.iterator() while(tmp.hasNext())
i tmp.next() if(s i) return true
return false
19
Introducing JPure!
Indicates iterator() returns fresh object
interface Collection _at_Fresh Object
iterator() interface Iterator _at_Pure
boolean hasNext() _at_Local Object
next() class Test ListltStringgt items
_at_Pure boolean has(String s) for(String i
items) if(s i) return true
return false
Indicates next() only modifies local state
_at_Pure boolean has(String s) Iterator tmp
tmp items.iterator() while(tmp.hasNext())
i tmp.next() if(s i) return true
return false
20
class ArrayList implements Collection
_at_Fresh Object iterator() return new
Iterator(data) static class Iterator
Object data int idx 0 _at_Pure boolean
hasNext() return idx lt data.size() _at_Local
Object next() return dataidx
  • Methods annotated _at_Fresh
  • Must return new objects
  • Or, values returned by methods marked _at_Fresh
  • Methods annotated _at_Local
  • May update local state
  • But otherwise must remain pure

21
Iterator Implementation
class ArrayList implements Collection
_at_Fresh Object iterator() return new
Iterator(data) static class Iterator
Object data int idx 0 _at_Pure boolean
hasNext() return idx lt data.size() _at_Local
Object next() return dataidx
  • Methods annotated _at_Fresh
  • Must return new objects
  • Or, values returned by methods marked _at_Fresh
  • Methods annotated _at_Local
  • May update local state
  • But otherwise must remain pure

22
class TList private int length private
_at_Local Object data private Type type
_at_Local public TList(Type t, int m) length
0 data new Objectm type t
_at_Local public void copy(TList dst) length
dst.length type dst.type data new
Objectdst.length for(int i0i!lengthi)
datai dst.datai
Locality Invariant 1 (Construction). When a new
object is constructed its locality is always
fresh.
Locality Invariant 2 (Preservation). When the
locality of a fresh object is modified, its
locality must remain fresh.
23
class TList private int length private
_at_Local Object data private Type type
_at_Local public TList(Type t, int m) length
0 data new Objectm type t
_at_Local public void copy(TList dst) length
dst.length type dst.type data new
Objectdst.length for(int i0i!lengthi)
datai dst.datai
Required for Invariant 1
Locality Invariant 1 (Construction). When a new
object is constructed its locality is always
fresh.
Locality Invariant 2 (Preservation). When the
locality of a fresh object is modified, its
locality must remain fresh.
24
class TList private int length private
_at_Local Object data private Type type
_at_Local public TList(Type t, int m) length
0 data new Objectm type t
_at_Local public void copy(TList dst) length
dst.length type dst.type data new
Objectdst.length for(int i0i!lengthi)
datai dst.datai
Required for Invariant 1
Safe under Invariant 2
Locality Invariant 1 (Construction). When a new
object is constructed its locality is always
fresh.
Locality Invariant 2 (Preservation). When the
locality of a fresh object is modified, its
locality must remain fresh.
25
Detailed Example
tmp
dst
this
_at_Local public void copy(TList dst) var tmp
dst.length this.length tmp tmp
dst.type this.type tmp tmp new
Objectdst.length this.data tmp
for(int i0i!lengthi) tmp
dst.datai this.datai tmp
LTHIS
LDST
?
26
Detailed Example
tmp
dst
this
_at_Local public void copy(TList dst) var tmp
dst.length this.length tmp tmp
dst.type this.type tmp tmp new
Objectdst.length this.data tmp
for(int i0i!lengthi) tmp
dst.datai this.datai tmp
LTHIS
LDST
?
LTHIS
LDST
?
27
Detailed Example
tmp
dst
this
_at_Local public void copy(TList dst) var tmp
dst.length this.length tmp tmp
dst.type this.type tmp tmp new
Objectdst.length this.data tmp
for(int i0i!lengthi) tmp
dst.datai this.datai tmp
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
28
Detailed Example
tmp
dst
this
_at_Local public void copy(TList dst) var tmp
dst.length this.length tmp tmp
dst.type this.type tmp tmp new
Objectdst.length this.data tmp
for(int i0i!lengthi) tmp
dst.datai this.datai tmp
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
29
Detailed Example
tmp
dst
this
_at_Local public void copy(TList dst) var tmp
dst.length this.length tmp tmp
dst.type this.type tmp tmp new
Objectdst.length this.data tmp
for(int i0i!lengthi) tmp
dst.datai this.datai tmp
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
30
Detailed Example
tmp
dst
this
_at_Local public void copy(TList dst) var tmp
dst.length this.length tmp tmp
dst.type this.type tmp tmp new
Objectdst.length this.data tmp
for(int i0i!lengthi) tmp
dst.datai this.datai tmp
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
31
Detailed Example
tmp
dst
this
_at_Local public void copy(TList dst) var tmp
dst.length this.length tmp tmp
dst.type this.type tmp tmp new
Objectdst.length this.data tmp
for(int i0i!lengthi) tmp
dst.datai this.datai tmp
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
32
Detailed Example
tmp
dst
this
_at_Local public void copy(TList dst) var tmp
dst.length this.length tmp tmp
dst.type this.type tmp tmp new
Objectdst.length this.data tmp
for(int i0i!lengthi) tmp
dst.datai this.datai tmp
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
33
Detailed Example
tmp
dst
this
_at_Local public void copy(TList dst) var tmp
dst.length this.length tmp tmp
dst.type this.type tmp tmp new
Objectdst.length this.data tmp
for(int i0i!lengthi) tmp
dst.datai this.datai tmp
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
LDST
34
Detailed Example
tmp
dst
this
_at_Local public void copy(TList dst) var tmp
dst.length this.length tmp tmp
dst.type this.type tmp tmp new
Objectdst.length this.data tmp
for(int i0i!lengthi) tmp
dst.datai this.datai tmp
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
LDST
LTHIS
LDST
LDST
35
Detailed Example
tmp
dst
this
_at_Local public void copy(TList dst) var tmp
dst.length this.length tmp tmp
dst.type this.type tmp tmp new
Objectdst.length this.data tmp
for(int i0i!lengthi) tmp
dst.datai this.datai tmp
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
?
LTHIS
LDST
LDST
LTHIS
LDST
LDST
LTHIS
LDST
LDST
36
Checking vs Inference
  • Purity Checker
  • Intraprocedural dataflow analysis
  • Uses static information about called methods
  • Checks fresh objects flow to _at_Fresh returns
  • Checks assignments to _at_Local fields are fresh
  • Checks assignments to other fields are in
    locality
  • Checks annotations overridden correctly
  • Purity Inference
  • Interprocedural dataflow analysis
  • Uses static call graph

37
(No Transcript)
38
Limitations
class Test private int hashCode public
boolean equals(Object o) if(hashCode()
o.hashCode()) return false public
int hashCode() if(hashCode -1) hashCode
return hashCode
  • Disappointment!
  • Object.equals() not inferred _at_Pure
  • Object.hashCode() not inferred _at_Pure

39
Conclusion
  • The JPure System
  • Built around Modularly Checkable Annotations
  • Interprocedural analysis infers annotations
  • Intraprocedural analysis checks annotations
  • Could be incorporated in Java Bytecode Verifier
  • Locality freshness help uncover more purity
  • 41 on average for benchmarks (vs 25 for simple)
  • See http//www.ecs.vuw.ac.nz/djp/jpure

40
Law of Locality
Law of Locality. When checking _at_Local
annotations, one can safely assume parameters are
not aliased (!)
  • Example
  • What if other aliased with this?
  • Applying Law of Locality seems counter-intuitive

class Test private int field _at_Local void
f(Test other) this.field 1
Write a Comment
User Comments (0)
About PowerShow.com