Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

48
Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL
  • date post

    22-Dec-2015
  • Category

    Documents

  • view

    226
  • download

    1

Transcript of Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Page 1: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Javari: Adding Reference Immutability to Java

Matthew Tschantz and Michael Ernst

MIT CSAIL

Page 2: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Protecting method arguments

static void print(readonly Date d) {

... // Cannot modify d

}

String toString() readonly {

... // Cannot modify the receiver

}

Page 3: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Protecting abstract state: observer methods

class Class {

private Object[] signers;

readonly Object[] getSigners() {

return signers; // JDK 1.1 bug

}

}

myClass.getSigners()[0] = “Sun”;

Page 4: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Protecting abstract state: observer methods

class Class {

private Object[] signers;

readonly Object[] getSigners() {

return signers; // Fixes JDK 1.1 bug

}

}

myClass.getSigners()[0] = “Sun”; // Error

Page 5: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Reference immutability

• A given reference cannot be used to modify its referent– other references to the object may modify it

• Is deep: the transitively reachable state (the abstract state) is protected

• Statically type checkable

Page 6: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Reference immutability versus object immutability

Object immutability: an object cannot be modified through any reference

Graph temp = new Graph();

// construct the graph

readonly Graph g = temp;

temp = null;

Page 7: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Motivation

• Provide compiler-enforced guarantees that a method will not change a given parameter

• Protect an object’s abstract state

• Prevent/detect errors

• Documentation

• Enable analyses and transformations

Page 8: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Other work• C++:

– unsound (unchecked casts) – non-transitive– no parametric polymorphism

• JAC [Kniesel 2001]: – unsound (subtyping, arrays)– return type mutability equals receiver's

• Javari2004 [Birka 2004]:– no parametric polymorphism– conflates assignability and mutability

• Object immutability– restricts programmer

Page 9: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Outline

• Language overview– assignability– mutability

• Parametric polymorphism

• Formal model

• Other language features

• Conclusion

Page 10: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Language overview

readonly Immutable reference

assignable Field may be reassigned even through a read-only reference

mutable Field may be mutated even through a

read-only reference

Page 11: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Readonly

readonly Date rd = new Date();

rd.year = 2005; // Compile-time error

rd.incrementDay(); // Compile-time error

rd = new Foo(); // OK

Page 12: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Mutability versus assignability

• Mutability– part of the type– readonly

final Date fd = null;readonly Date rd = null; fd = new Date(); // Error: finalrd = null; // OK

Date d1 = fd; // OKDate d2 = rd; // Error: wrong type

• Assignability– not part of the type– final

Page 13: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Type system

Every type (mutable) T has readonly T as a supertype

readonly Object

readonly Date

/*mutable*/ Object

/*mutable*/ Date

Page 14: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Outline

• Language overview– assignability – mutability

• Parametric polymorphism

• Formal model

• Other language features

• Conclusion

Page 15: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Assignability

Whether a reference may be assigned to.class Appointment {

final Date time; // Same as in Java

assignable int room;

}

Appointment appoint;

appoint.time = new Date(); // Error

appoint.room = 250; // OK

Page 16: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Assignability modifiers final: May never be assigned

assignable: May always be assigned; the default for locals

this-assignable: – May be assigned through a mutable reference– May not be assigned through a readonly reference– Only applicable to fields; the default– The assignability depends on the mutability of the

enclosing object: “this”

Page 17: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Assignability exampleclass Bicycle {

final int id; // Never changes

assignable int hashCode; // A cache

/*this-assign*/ int gear; // Abstract state

}

/*mutable*/ Bicycle b;

readonly Bicycle rb;

Page 18: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

finalclass Bicycle {

final int id; // Never changes

assignable int hashCode; // A cache

/*this-assign*/ int gear; // Abstract state

}

/*mutable*/ Bicycle b;

readonly Bicycle rb;

b.id = 5; // Error

rb.id = 5; // Error

Resolved assignability of ref.f

Declared assignability of f

Resolved mutability of ref

mutable readonly

final unassignable unassignable

Page 19: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

assignableclass Bicycle {

final int id; // Never changes

assignable int hashCode; // A cache

/*this-assign*/ int gear; // Abstract state

}

/*mutable*/ Bicycle b;

readonly Bicycle rb;

b.hashCode = 5; // OK

rb.hashCode = 5; // OK

Resolved assignability of ref.f

Declared assignability of f

Resolved mutability of ref

mutable readonly

final unassignable unassignable

assignable assignable assignable

Page 20: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

this-assignableclass Bicycle {

final int id; // Never changes

assignable int hashCode; // A cache

/*this-assign*/ int gear; // Abstract state

}

/*mutable*/ Bicycle b;

readonly Bicycle rb;

b.gear = 5; // OK

Resolved assignability of ref.f

Declared assignability of f

Resolved mutability of ref

mutable readonly

final unassignable unassignable

assignable assignable assignable

this-assignable assignable unassignable

Page 21: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

this-assignableclass Bicycle {

final int id; // Never changes

assignable int hashCode; // A cache

/*this-assign*/ int gear; // Abstract state

}

/*mutable*/ Bicycle b;

readonly Bicycle rb;

b.gear = 5; // OK

rb.gear = 5; // Error

Resolved assignability of ref.f

Declared assignability of f

Resolved mutability of ref

mutable readonly

final unassignable unassignable

assignable assignable assignable

this-assignable assignable unassignable

Page 22: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Outline

• Language overview– assignability – mutability

• Parametric polymorphism

• Formal model

• Other language features

• Conclusion

Page 23: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

MutabilityWhether an object’s transitive abstract state

may be modified

class Date {

/*this-assignable*/ int year;

}

/*mutable*/ Date d;

readonly Date rd;

d.year = 2005; // OK

rd.year = 2005; // Error

Page 24: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Mutability modifiers

readonly: May never be mutated

mutable: May always be mutated; the default for locals

this-mutable: – May be mutated through mutable reference – May not be mutated through readonly references– Only applicable to fields; the default– The mutability depends on the mutability of the enclosing

class: “this”

Page 25: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Mutability exampleclass Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal;}/*mutable*/ Account a;readonly Account ra;

Page 26: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

readonlyclass Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal;}/*mutable*/ Account a;readonly Account ra; a.owner.setName(“Bob”); // Errorra.owner.setName(“Bob”); // Error

Mutability of ref.f

Declared mutability of f

Resolved mutability of ref

mutable readonly

readonly readonly readonly

Page 27: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

mutableclass Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal;}/*mutable*/ Account a;readonly Account ra; a.requests.add(“checkBalance”); // OKra.requests.add(“checkBalance”); // OK

Mutability of ref.f

Declared mutability of f

Resolved mutability of ref

mutable readonly

readonly readonly readonly

mutable mutable mutable

mutable excludes requests from the abstract state of the object

Page 28: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

this-mutableclass Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal;}/*mutable*/ Account a;readonly Account ra; a.balance.withdraw(1000); // OK

Mutability of ref.f

Declared mutability of f

Resolved mutability of ref

mutable readonly

readonly readonly readonly

mutable mutable mutable

this-mutable mutable <? readonly>

Page 29: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

this-mutableclass Account { readonly Customer owner; mutable RequestLog requests; /*this-mut*/ Balance bal;}/*mutable*/ Account a;readonly Account ra; a.balance.withdraw(1000); // OKra.balance.withdraw(1000); // Error

Mutability of ref.f

Declared mutability of f

Resolved mutability of ref

mutable readonly

readonly readonly readonly

mutable mutable mutable

this-mutable mutable <? readonly>

Page 30: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

this-mutable fields reached through a readonly reference

readonly, right?

Page 31: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

this-mutable fields reached through a readonly reference

readonly, right? NO, would result in type loophole allowing one to

convert a readonly reference to a mutable reference:

Page 32: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

this-mutable fields reached through a readonly reference

readonly, right? NO, would result in type loophole allowing one to

convert a readonly reference to a mutable reference:

class Student { assignable /*this-mut*/ GradeReport grades;}/*mutable*/ Student s = new Student();readonly Student rs = s;readonly GradeReport rg;/*mutable*/ GradeReport g;

rs.grades = rg; //readonly assigned to this-mutableg = s.grades; //this-mutable assigned to mutable

Page 33: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

this-mutable fields reached through a readonly reference

Solution: Disallow readonly references to be assigned to a this-mutable field

class Student { assignable /*this-mut*/ GradeReport grades;}

this-mutable fields are• taken out at readonly GradeReport • written to as mutable GradeReport

Page 34: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

this-mutable fields reached through a readonly reference

Solution: Disallow readonly references to be assigned to a this-mutable field

class Student { assignable /*this-mut*/ GradeReport grades;}

this-mutable fields are • taken out at readonly GradeReport • written to as mutable GradeReport

Using wildcards and bounds, the type of grades can be written as:<? extends readonly GradeReport super mutable GradeReport>

Notation: <? readonly GradeReport>

Page 35: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Outline

• Language overview– assignability– mutability

• Parametric polymorphism

• Formal model

• Other language features

• Conclusion

Page 36: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Uses of parametric classes

Local variable declarations: /*mut*/ List</*mut*/ Date> a; // add, mutate

/*mut*/ List<readonly Date> b; // add

readonly List</*mut*/ Date> c; // mutate

readonly List<readonly Date> d; // neither

(Arrays are similar)

Page 37: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Inside parametric classesType arguments include mutability

Library cannot write:

class C<T> {

mutable T x;

}

C<readonly Date> y; // Conflicting types

Page 38: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Inside parametric classesType arguments include mutability

Library cannot write:

class C<T> {

mutable T x;

}

C<readonly Date> y; // Conflicting types

Library can force a mutable type using a bound:;

class C<T extends mutable Object> {

T x;

}

Page 39: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

this-mutable type arguments

class Wheel { /*this-mut*/ List</*this-mut*/ Spoke> spokes;}

/*mutable*/ Wheel w;readonly Wheel rw;

w.spokes has type /*mut*/ List</*mut*/ Spoke>

/*mut*/ List</*mut*/ Spoke> w = w.spokes; // OK

Page 40: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

this-mutable type arguments

class Wheel { /*this-mut*/ List</*this-mut*/ Spoke> spokes;}

/*mutable*/ Wheel w;readonly Wheel rw;

rw.spokes has type ? readonly List<? readonly Spoke>

readonly List<? readonly Spoke> x = rw.spokes; // OK

readonly List<readonly Spoke> y = rw.spokes; // Errorreadonly List</*mutable*/ Spoke> z = rw.spokes; // Error

Page 41: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Outline

• Language overview– assignability– mutability

• Parametric polymorphism

• Formal model

• Other language features

• Conclusion

Page 42: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Formal model

• Core language

• Extension to Featherweight Generic Java

• Type soundness proof underway– Subject reduction and progress theorems

• Proof that an object is never modified if only a readonly reference exists

Page 43: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Outline

• Language overview– assignability– mutability

• Parametric polymorphism

• Formal model

• Other language features

• Conclusion

Page 44: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Reflection• Method.invoke continues to return

mutable references– dynamically checks type signature: return type

must be mutable

• New method Method.invokeReadonly returns a readonly reference– no dynamic checks

• Type, including mutability, of arguments (including receiver) is checked at compile time.

Page 45: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Serialization

• Add a readonly-ness bit to the serialized form.

• Check readonly-ness bit if one attempts to deserialization an object to a mutable reference.

Page 46: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Reducing code duplication

romaybe keyword templates over methods

class Conference { /*this-mutable*/ Date d;

We wish to write two (overloaded) methods:

readonly Date getDate() readonly { return d; } /*mutable*/ Date getDate() /*mutable*/ { return d; }

Syntactic sugar:

romaybe Date getDate() romaybe { return d; }}

Page 47: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Outline

• Language overview– assignability– mutability

• Parametric polymorphism

• Formal model

• Other language features

• Conclusion

Page 48: Javari: Adding Reference Immutability to Java Matthew Tschantz and Michael Ernst MIT CSAIL.

Contributions

• Transitive reference immutability

• Distinguishes assignability and mutability

• Formal model

• Type system for full Java including parametric polymorphism, reflection, and serialization

• Templates to reduce code duplication

• Interoperable with Java