Type-based Object Immutability with Flexible Initialization - - PowerPoint PPT Presentation

type based object immutability with flexible
SMART_READER_LITE
LIVE PREVIEW

Type-based Object Immutability with Flexible Initialization - - PowerPoint PPT Presentation

Type-based Object Immutability with Flexible Initialization Christian Haack 1 , 2 Erik Poll 1 1 Radboud University, Nijmegen, The Netherlands 2 aicas GmbH, Karlsruhe, Germany ECOOP 2009 in Genoa, July 510 http://mobius.inria.fr What is this


slide-1
SLIDE 1

Type-based Object Immutability with Flexible Initialization

Christian Haack1,2 Erik Poll1

1Radboud University, Nijmegen, The Netherlands 2aicas GmbH, Karlsruhe, Germany

ECOOP 2009 in Genoa, July 5–10 http://mobius.inria.fr

slide-2
SLIDE 2

What is this Talk About?

A pluggable type system ... ... for statically checking various immutability properties ... ... in Java-like languages.

Christian Haack, Erik Poll Type-based Object Immutability 2

slide-3
SLIDE 3

Kinds of Immutability

Object immutability. An object is immutable if its state cannot be modified. Class immutability. An immutable class is a class whose instances cannot be modified.

Closed world: assumes that clients of immutable classes follow the rules of the pluggable type system. Open world: assumes that clients only follow Java’s standard typing rules.

Read-only references. A reference is read-only if the state of the object it refers to cannot be modified through this reference.

Christian Haack, Erik Poll Type-based Object Immutability 3

slide-4
SLIDE 4

Object Immutability and Object Initialization

Immutable objects mutate during their initialization phase! Tying object initialization to object constructors ... ... is neither sufficient ...

E.g., immutable arrays, immutable collections implemented in terms of mutable collection APIs, immutable cyclic structures.

... nor does it simplify the type analysis.

Java imposes no restrictions on constructor bodies.

Christian Haack, Erik Poll Type-based Object Immutability 4

slide-5
SLIDE 5

Design Goals

support the various kinds of immutability support object initialization outside constructors self-containedness (we do not want to build on top of other more general systems) compatibility with JSR 308 annotations

a version with explicit ghost commands that indicate the end of object initialization phases an inference algorithm that infers the end of object initialization phases

Christian Haack, Erik Poll Type-based Object Immutability 5

slide-6
SLIDE 6

Type Qualifiers: RdWr and Rd

Type Qualifiers. q ::= RdWr read-write access (default) (aka. @Mutable) Rd read-only access (aka. @Immutable)

Christian Haack, Erik Poll Type-based Object Immutability 6

slide-7
SLIDE 7

Type Qualifiers: RdWr and Rd

Type Qualifiers. q ::= RdWr read-write access (default) (aka. @Mutable) Rd read-only access (aka. @Immutable) Types. T ::= q C If an object has type Rd C then its fields may only be read.

Christian Haack, Erik Poll Type-based Object Immutability 6

slide-8
SLIDE 8

Type Qualifiers: RdWr and Rd

Type Qualifiers. q ::= RdWr read-write access (default) (aka. @Mutable) Rd read-only access (aka. @Immutable) Types. T ::= q C If an object has type Rd C then its fields may only be read.

class C { int f; } static void m(Rd C x) { x.f = 42; // TYPE ERROR } static void k(RdWr C x) { x.f = 42; // OK }

Christian Haack, Erik Poll Type-based Object Immutability 6

slide-9
SLIDE 9

Type Qualifiers: RdWr and Rd

Type Qualifiers. q ::= RdWr read-write access (default) (aka. @Mutable) Rd read-only access (aka. @Immutable) Types. T ::= q C If an object has type Rd C then its fields may only be read.

class C { int f; } static void m(Rd C x) { x.f = 42; // TYPE ERROR } static void k(RdWr C x) { x.f = 42; // OK }

Soundness. Well-typed programs never write to Rd-objects.

Christian Haack, Erik Poll Type-based Object Immutability 6

slide-10
SLIDE 10

Type Qualifiers: Any (aka @Readonly-Reference)

Type Qualifiers. q ::= · · · Any “the referred object is either Rd or RdWr”

Subqualifying. Rd <: Any RdWr <: Any Subtyping. p <: q C <: D p C <: q D

Writes through Any-references are prohibited.

interface Util { void foo(int Any [] x); } static void m(Util util) { int[] a = new int RdWr [] {42,43,44}; util.foo(a); assert a[0] == 42; }

Christian Haack, Erik Poll Type-based Object Immutability 7

slide-11
SLIDE 11

The Access Right is a Class Parameter

Classes have a special class parameter MyAccess. MyAccess refers to the access qualifier for this.

class Point { int x; int y; } class Square { MyAccess Point upperleft; MyAccess Point lowerright; } static void m(Rd Square s) { s.upperleft = new Point(); // TYPE ERROR s.upperleft.x = 42; // TYPE ERROR }

Christian Haack, Erik Poll Type-based Object Immutability 8

slide-12
SLIDE 12

The Initialization Discipline

Initialization Token. n ∈ Token token for initializing a set of related objects Ghost command (has no effect at runtime). newtoken n create a new initialization token

Christian Haack, Erik Poll Type-based Object Immutability 9

slide-13
SLIDE 13

The Initialization Discipline

Initialization Token. n ∈ Token token for initializing a set of related objects Ghost command (has no effect at runtime). newtoken n create a new initialization token Type Qualifier. Fresh(n) fresh object under initialization

Typical use: newtoken n; new Fresh(n) C(); new Fresh(n) D(); . . . Fresh objects are writeable (even if they later turn immutable).

Christian Haack, Erik Poll Type-based Object Immutability 9

slide-14
SLIDE 14

The Initialization Discipline

Initialization Token. n ∈ Token token for initializing a set of related objects Ghost command (has no effect at runtime). newtoken n create a new initialization token Type Qualifier. Fresh(n) fresh object under initialization

Typical use: newtoken n; new Fresh(n) C(); new Fresh(n) D(); . . . Fresh objects are writeable (even if they later turn immutable).

Ghost command (has no effect at runtime). commit Fresh(n) as q globally convert Fresh(n) to q

Christian Haack, Erik Poll Type-based Object Immutability 9

slide-15
SLIDE 15

The Initialization Discipline

Initialization Token. n ∈ Token token for initializing a set of related objects Ghost command (has no effect at runtime). newtoken n create a new initialization token Type Qualifier. Fresh(n) fresh object under initialization

Typical use: newtoken n; new Fresh(n) C(); new Fresh(n) D(); . . . Fresh objects are writeable (even if they later turn immutable).

Ghost command (has no effect at runtime). commit Fresh(n) as q globally convert Fresh(n) to q

static char Rd [] copy (char RdWr [] w) { newtoken n; char[] r = new char Fresh(n) [w.length]; for (int i=0; i++; i < w.length) r[i] = w[i]; commit Fresh(n) as Rd; return r; }

Christian Haack, Erik Poll Type-based Object Immutability 9

slide-16
SLIDE 16

Soundness of Commit (Scoping of Init-Tokens)

Fields cannot have Fresh(n)-qualifiers.

class C { Fresh(n) D x; // TYPE ERROR: n out of scope }

Christian Haack, Erik Poll Type-based Object Immutability 10

slide-17
SLIDE 17

Soundness of Commit (The Heap Invariant)

RdWr-object Rd-object

Initialized Fresh(red) Fresh(blue)

Heap Invariant.

There are no ingoing references into Fresh-regions.

N.B.: references inside Fresh regions are possible, by MyAccess qualifier on fields.

Christian Haack, Erik Poll Type-based Object Immutability 11

slide-18
SLIDE 18

Soundness of Commit (Meth. Confinement of Init-Tokens)

Each initialization token is to confined to a single method.

Rd C commit(Fresh(n) C x) { // TYPE ERROR: n out of scope commit Fresh(n) as Rd; return x; }

So, only the method that generates an initialization token has the right to commit the associated fresh region.

Christian Haack, Erik Poll Type-based Object Immutability 12

slide-19
SLIDE 19

Soundness of Commit (The Big Picture)

RdWr-object Rd-object

Initialized Fresh(red) Fresh(blue)

top rest

Stack

Christian Haack, Erik Poll Type-based Object Immutability 13

slide-20
SLIDE 20

Soundness of Commit (The Big Picture)

RdWr-object Rd-object

Initialized Fresh(red) Fresh(blue)

top rest

Stack

commit Fresh(red) as Rd

Christian Haack, Erik Poll Type-based Object Immutability 13

slide-21
SLIDE 21

Soundness of Commit (The Big Picture)

RdWr-object Rd-object

Initialized Fresh(red) Fresh(blue)

top rest

Stack

commit Fresh(red) as Rd

Christian Haack, Erik Poll Type-based Object Immutability 13

slide-22
SLIDE 22

Soundness of Commit (The Big Picture)

RdWr-object Rd-object

Initialized Fresh(blue)

top rest

Stack

commit Fresh(red) as Rd red region turns black

Christian Haack, Erik Poll Type-based Object Immutability 13

slide-23
SLIDE 23

Soundness of Commit (The Big Picture)

RdWr-object Rd-object

Initialized Fresh(blue)

top rest

Stack

commit Fresh(red) as Rd red region turns black colors of references on stack must be adjusted

Christian Haack, Erik Poll Type-based Object Immutability 13

slide-24
SLIDE 24

Qualifier Polymorphism for Methods

static void copy(Point src, Point dst) { dst.x = src.x; dst.y = src.y; }

It should be allowed to pass actual dst-parameters of types RdWr Point and Fresh(n) Point.

This method is similar to arraycopy(). arraycopy() is called in constructors of immutable Strings.

Christian Haack, Erik Poll Type-based Object Immutability 14

slide-25
SLIDE 25

Qualifier Polymorphism for Methods (cont.)

Rd Any RdWr Fresh(n) Fresh(m) · · ·

Christian Haack, Erik Poll Type-based Object Immutability 15

slide-26
SLIDE 26

Qualifier Polymorphism for Methods (cont.)

Rd Any RdWr Fresh(n) Fresh(m) · · · Writeable

Writeable can only be used as a bound, not as a type qualifier.

Christian Haack, Erik Poll Type-based Object Immutability 15

slide-27
SLIDE 27

Qualifier Polymorphism for Methods (cont.)

Rd Any RdWr Fresh(n) Fresh(m) · · · Writeable

Writeable can only be used as a bound, not as a type qualifier. Typing rule for field sets (incomplete sketch). x : q C q extends Writeable x.f = v : ok

static <a, b extends Writeable> void copy(a Point src, b Point dst) { dst.x = src.x; dst.y = src.y; }

Christian Haack, Erik Poll Type-based Object Immutability 15

slide-28
SLIDE 28

Receiver Qualifiers (supported by JSR 308)

JSR 308 provides a slot for annotations on the receiver type. Inspectors can be called on any receivers. Mutators can only be called on Writeable receivers.

class Hashtable<K,V> { <a> V get(K key) a { . . . } // INSPECTOR <a extends Writeable> V put(K key, V value) a { . . . } // MUTATOR } newtoken n; Hashtable<String,String> t = new <Fresh(n)> Hashtable<String,String>(); t.put("Alice", "Amsterdam"); t.put("Bob", "Berlin"); commit Fresh(n) as Rd; t.get("Alice"); // OK t.put("Charlie", "Chicago"); // TYPE ERROR

Christian Haack, Erik Poll Type-based Object Immutability 16

slide-29
SLIDE 29

Constructors

Constructors must have one of the following forms:

1

<¯ a extends ¯ B> q C( ¯ T ¯ x) p { body } Typically: <a extends Writeable> a C( ¯ T ¯ x) a { body } Caller commits. Better choice most of the time.

2

<¯ a extends ¯ B> q C( ¯ T ¯ x) { newtoken n; body } Constructor commits. Useful for class immutability in an open world.

It is disallowed to call constructors of the second form using super(). The second form is therefore most appropriate for final classes.

Christian Haack, Erik Poll Type-based Object Immutability 17

slide-30
SLIDE 30

Qualifier-Polymorphic Methods and Confinement

Rd Any RdWr Fresh(n) Fresh(m) · · · Writeable

static <a> void foo(int a [] x) does not write to object x through reference x does not create a reference to object x on the heap static void faa(int Any [] x) does not write to object x through reference x may create a reference to object x on the heap static <a extends Writeable> void fee(int a [] x) may write to object x through reference x does not create a reference to object x on the heap

Christian Haack, Erik Poll Type-based Object Immutability 18

slide-31
SLIDE 31

Class Immutability (Open World)

Immutable final class String { private final char MyAccess [] arr; . . . }

Rules. immutable classes must be final and direct subclasses of Object methods and constructors may only call static or final methods (transitively) all fields must be private or final types of public methods must have the following form:

<a> U m( ¯ T ¯ x) a { . . . } where MyAccess and a do not occur in U.

constructors must have the following form

Rd C( ¯ T ¯ x) { newtoken n; . . . ; commit Fresh(n) as Rd; } where MyAccess does not occur in ¯ T.

Christian Haack, Erik Poll Type-based Object Immutability 19

slide-32
SLIDE 32

Threads

We enforce that objects are committed before they get thread-shared.

class Thread { void run() RdWr { } void start(); // Treated specially. The type system uses run()’s type. } Rd Any RdWr Fresh(n) Fresh(m) · · · Writeable

Christian Haack, Erik Poll Type-based Object Immutability 20

slide-33
SLIDE 33

Local Annotation Inference

An algorithm that infers all annotations inside method and constructor bodies. In particular: all ghost statements are inferred. The algorithm is syntax-directed. Basic idea: insert commit-statements lazily whenever this is required to satisfy annotations on fields, methods and constructors.

Christian Haack, Erik Poll Type-based Object Immutability 21

slide-34
SLIDE 34

Contributions

A pluggable type system for immutability: Object immutability, class immutability and read-only references. Simple and direct.

Annotation language is small: only Rd, RdWr, Any and qualifier

  • polymorphism. (Fresh can always be inferred.)

Only annotations on types are needed. (No effect annotations, constraints, pre/postconditions, loop invariants, or the like.)

Flexible object initialization (not tied to constructors).

Without the need for complex aliasing annotations or destructive reads, as in systems that support typestate changes through unique references.

Christian Haack, Erik Poll Type-based Object Immutability 22