1 / 21

Ownership and Immutability in Generic Java (OIGJ)

Yoav Zibin , Alex Potanin Paley Li, Mahmood Ali, and Michael D. Ernst Presenter: Yossi Gil. Ownership and Immutability in Generic Java (OIGJ). Ownership and Immutability. Owner-as-dominator All reference-chains from a root to an object pass via its owner

gautam
Télécharger la présentation

Ownership and Immutability in Generic Java (OIGJ)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. YoavZibin, Alex Potanin Paley Li, Mahmood Ali, and Michael D. Ernst Presenter: Yossi Gil Ownership and Immutability in Generic Java (OIGJ)

  2. Ownership and Immutability Owner-as-dominator All reference-chains from a root to an object pass via its owner An object cannot leak beyond its owner No aliases to internal state Mutable object Fields can be assigned Immutable object Raw state:Fields can be assigned Cooked state:Fields cannot be assigned ReadOnly references Ownership Immutability How can we benefit from a combination?

  3. Benefits from Ownership + Immutability Previous work Relaxed owner-as-dominator to owner-as-modifier ReadOnly references can be freely shared Constrains modification instead of aliasing, i.e., only the owner can modify an object OIGJ’s novel idea: Prolong the cooking phase by using ownership information Makes it easier to create immutable cyclic structures Many objects must be raw simultaneously to create cyclic structures

  4. Cooking immutable objects Previous work An object becomes cooked when its constructor finishes OIGJ’s observation An object becomes cooked when its owner’s constructor finishes The outside world will not see this cooking phase

  5. Cooking Example: LinkedList The list owns its entries Therefore, it can mutate them even after their constructor finished 1: LinkedList(Collection<E> c) { 2: this(); 3: Entry<E> succ = this.header, pred = succ.prev; 4: for (E e : c) { 5: Entry<E> entry = new Entry<E>(e,succ,pred); 6: // It’s illegal to change an entry after it’s cooked. 7: pred.next = entry; pred = entry; 8: } 9: succ.prev =pred; 10: }

  6. Contributions Formalization Formalized the concepts of raw/cooked objects and wildcards as owner parameters, and proved soundness Flexibility OIGJ can type-check more code than previous work: cyclic structures, the factory and visitor design patterns No refactoring of existing code Verified that Java’s collection classes are properly encapsulated (using only 3 ownership annotations) Simplicity Use generics to express immutability and ownership

  7. Hierarchies in OIGJ ReadOnly World Raw Immut This Mutable Ownership hierarchy World – anyone can access This – this owns the object Immutability hierarchy ReadOnly– no modification Raw– object under construction

  8. OIGJ syntax: fields (1 of 2) Two new generic parameters were added 1:class Foo<O extends World, I extends ReadOnly> { 2: // An immutable reference to an immutable date. Date<O,Immut>imD = new Date<O,Immut>(); 3: // A mutable reference to a mutable date. Date<O,Mutable>mutD = new Date<O,Mutable>(); 4: // A readonly reference to any date. Both roD and imD cannot mutate // their referent, however the referent of roD might be mutated by an // alias, whereas the referent of imD is immutable. Date<O,ReadOnly>roD = ... ? imD : mutD; 5: // A date with the same owner and immutability as this Date<O,I>sameD; 6: // A date owned by this; it cannot leak. Date<This,I>ownedD; 7: // Anyone can access this date. Date<World,I>publicD;

  9. OIGJ syntax: methods (2 of 2) Method guard <T extends U>?has a dual purpose: The method is included only if T extends U Inside the method, the bound of Tis U. 8 : // Can be called on any receiver; cannot mutate this. <I extends ReadOnly>? intreadonlyMethod(){...} 9 : // Can be called only on mutable receivers; can mutate this. <I extends Mutable>? void mutatingMethod(){...} 10: // Constructor that can create (im)mutable objects. <I extends Raw>? Foo(Date<O,I> d) { 11: this.sameD = d; 12: this.ownedD = new Date<This,I>(); 13: // Illegal, because sameDcame from the outside. // this.sameD.setTime(...); 14: // OK, because Raw is transitive for owned fields. this.ownedD.setTime(...); 15: }

  10. LinkedList Example 1 : class Entry<O,I,E> { 2 : E element; 3 : Entry<O,I,E> next, prev; … 4 : } 5 : class LinkedList<O,I,E> { 6 : Entry<This,I,E> header; … 7 : <I extends Raw>?LinkedList( 8 : Collection<?,ReadOnly,E> c) { 9 : this(); this.addAll(c); 10: } 11: <I extends Raw>? void addAll( 12: Collection<?,ReadOnly,E> c) { 13: Entry<This,I,E> succ = this.header, 14: pred = succ.prev; 15: for (E e : c) { 16: Entry<This,I,E> en = 17: new Entry<This,I,E>(e,succ,pred); 18: pred.next = en; pred = en; } 19: succ.prev = pred; 20: }

  11. OIGJ typing rules Ownership nesting Field access Field assignment Method invocation Method guards Raw parameter can be used only in method guards (see the paper for all rules, such as inner classes, covariant subtyping)

  12. Ownership nesting The main owner parameter must be inside any other owner parameter. List<This, I,Date<World,I>> l1; // Legal nesting List<World,I,Date<This, I>> l2; // Illegal! It’s illegal because we can store l2 in this variable: public static Object<World,ReadOnly> alias_l2;

  13. Field access/assignment this-owned fields can be accessed/assigned only via this 1: class Foo<O extends World, I extends ReadOnly> { 2: Date<This,I> ownedD; // this-owned field 3: Date<O,I> sameD; 4: <I extends Mutable>? void bar(Foo<This,I> other) { 5: this.ownedD = …; // Legal: assign via this 6: other.ownedD= …; // Illegal: not via this 7: other.sameD= …; // Legal: not this-owned 8: }

  14. Field assignment A field can be assigned only if the object is Raw or Mutable. If it is Raw, then the object must be this or this-owned. 1 : class Foo<O extends World, I extends ReadOnly> { 2 : Date<O,I> sameD; 3 : <I extends Raw>? void bar( 4 : Foo<?,Mutable> mutableFoo, 5 : Foo<?,ReadOnly> readonlyFoo, 6 : Foo<?,I> rawFoo1, 7 : Foo<This,I> rawFoo2) { 8 : mutableFoo.sameD = …; // Legal: object is Mutable 9 : readonlyFoo.sameD = …; // Illegal: object is not Raw nor Mutable 10: rawFoo1.sameD = …; // Illegal: object is not this nor this-owned 11: rawFoo2.sameD = …; // Legal: object is Raw and this-owned 12: this.sameD= …; // Legal: object is Raw and this 13: }

  15. Method invocation Method invocation is the same as field access/assignment: If any parameter is this-owned, then the receiver must be this. If the guard is Raw and the object is Raw, then the receiver must be this or this-owned. 1 : class Foo<O extends World, I extends ReadOnly> { 2 : Date<This,I> m1() { … } // Parameter is this-owned 3 : <I extends Raw>? void m2() { … } 4 : <I extends Raw>? void bar( 5 : Foo<?,I> rawFoo1, 6 : Foo<This,I> rawFoo2) { 7 : this.m1(); // Legal: object is this 8 : rawFoo2.m1(); // Illegal: object is not this 9 : rawFoo1.m2(); // Illegal: object is not this nor this-owned 10: rawFoo2.m2(); // Legal: both Raw and object is this-owned 11: this.m2(); // Legal: both Raw and object is this 12: }

  16. Method guards Guard “<T extends U>?” has a dual purpose: The receiver’s T must be a subtype of U. Inside the method, the bound of T is U. 1: class Foo<O extends World, I extends ReadOnly> { 2: <I extends Raw>? void rawM() { … } 3: <I extends Mutable>? void bar( 4: Foo<?,ReadOnly> readonlyFoo, 5: Foo<?,I> mutableFoo) { 6: readonlyFoo.rawM(); // Illegal: ReadOnly is not a subtype of Raw // The bound of I in this method is Mutable 7: mutableFoo.rawM(); // Legal: Mutableis a subtype of Raw 8: this.rawM(); // Legal: Mutable is a subtype of Raw 9: } Conditional Java (cJ) proposed method guards for Java

  17. Formalization: Featherweight OIGJ • Novel idea: Cookers • Every location l in the heap is of the form: • l' is the owner of l • l” is the cooker of l, i.e., when the constructor of l” finishes then l becomes cooked • We keep track of the set of ongoing constructors • Subtyping rules connect cookers and owners or lFoo<l’,Mutable> lFoo<l’,Immut > l" • Proved soundness and type preservation

  18. Case studies • From Generics to Annotations • Date<O,I>  @OI Date • Implementation uses the checkers framework • Only 1600 lines of code (but still a prototype) • Requires type annotations available in Java 7 • Java’s Collections case study • 77 classes, 33K lines of code • 85 ownership-related annotations • 46 immutability-related annotations

  19. Case studies conclusions • Verified that collections own their representation • Method get must be Mutable! • new LinkedHashMap(100, 1, /*accessOrder=*/ true) • Order of iteration is the order in which its entries were last accessed • Method overriding can only make the guard less strict • Method clone is problematic • Clone makes a shallow copy that breaks ownership • Our suggestion: compiler-generated clone that nullifies fields, and then calls a copy-constructor

  20. Conclusions • Ownership Immutability Generic Java (OIGJ) • Simple, intuitive, small • Static – no runtime penalties (like generics) • Backward compatible, no JVM changes • High degree of polymorphism using generics and safe covariant subtyping • Case study proving usefulness • Formal proof of soundness

  21. Future work Inferring ownership and immutability annotations Bigger case study Extending OIGJ owner-as-modifier uniqueness or external uniqueness Questions?

More Related