Presentation is loading. Please wait.

Presentation is loading. Please wait.

Ownership Types for Object Encapsulation Barbara Liskov Chandrasekhar Boyapati Liuba Shrira Laboratory for Computer Science Massachusetts Institute of.

Similar presentations


Presentation on theme: "Ownership Types for Object Encapsulation Barbara Liskov Chandrasekhar Boyapati Liuba Shrira Laboratory for Computer Science Massachusetts Institute of."— Presentation transcript:

1 Ownership Types for Object Encapsulation Barbara Liskov Chandrasekhar Boyapati Liuba Shrira Laboratory for Computer Science Massachusetts Institute of Technology {liskov, chandra, liuba}@lcs.mit.edu

2 Outline Object Encapsulation Object Encapsulation Ownership Types Ownership Types Upgrades in Persistent Object Stores Upgrades in Persistent Object Stores

3 Modular Reasoning Goal is local reasoning about correctness Goal is local reasoning about correctness  Prove a class meets its specification, using only specifications but not code of other classes Crucial when dealing with large programs Crucial when dealing with large programs Requires no interference from code outside the class Requires no interference from code outside the class  Objects must be encapsulated

4 Consider a Set object s implemented using a Vector object v Consider a Set object s implemented using a Vector object v Object Encapsulation v ~ ~ so Local reasoning about s is possible Local reasoning about s is possible  If objects outside s do not access v  That is, if v is encapsulated within s

5 Encapsulation In general, all objects that s depends on must be encapsulated within s In general, all objects that s depends on must be encapsulated within s s depends on x if mutations of x affect behavior of s s depends on x if mutations of x affect behavior of s  Leino, Nelson ( SCR ’00 )  Detlefs, Leino, Nelson ( SRC ’98 )

6 Examples Rep invariant for Set: no-dups Rep invariant for Set: no-dups  Then, size of vector is size of set  Then, remove stops at match Clearly, v must be inside s Clearly, v must be inside s s v

7 Examples What does no-dups mean? What does no-dups mean?  ! e1.equals(e2), for any elements e1 & e2 So set does not depend on elements if elements are immutable So set does not depend on elements if elements are immutable s v

8 Iterators and Encapsulation Iterators require access to representation Iterators require access to representation Okay if violations of encapsulation limited to the same module Okay if violations of encapsulation limited to the same module s v i

9 Ownership Types Goal is to enforce encapsulation statically Goal is to enforce encapsulation statically s v Programmer can declare s owns v Programmer can declare s owns v System ensures v is encapsulated in s System ensures v is encapsulated in s

10 Ownership Types Every object has an owner Every object has an owner Owner can be another object or world Owner can be another object or world Ownership relation forms a tree Ownership relation forms a tree Owner of an object cannot change Owner of an object cannot change world

11 Ownership Types for Encapsulation If an object owns objects it depends on If an object owns objects it depends on Then type system enforces encapsulation Then type system enforces encapsulation  If v is inside s and o is outside  Then o cannot access v v ~ ~ so

12 Ownership Types world

13 class TStack { TNode head; TNode head; void push(T value) {…} void push(T value) {…} T pop() {…} T pop() {…}} class TNode { TNode next; TNode next; T value; T value; …} class T {…} TStack Example (No Owners) value next head value next value next … … … TStack TNode T

14 TStack Example (With Owners) class TStack  stackOwner, TOwner  { TNode  this, TOwner  head; TNode  this, TOwner  head;} class TNode  nodeOwner, TOwner  { TNode  nodeOwner, TOwner  next; TNode  nodeOwner, TOwner  next; T  TOwner  value; T  TOwner  value;} class T  TOwner  {…} TStack TNode T Classes are parameterized with owners

15 TStack Example class TStack  stackOwner, TOwner  { TNode  this, TOwner  head; TNode  this, TOwner  head;} class TNode  nodeOwner, TOwner  { TNode  nodeOwner, TOwner  next; TNode  nodeOwner, TOwner  next; T  TOwner  value; T  TOwner  value;} class T  TOwner  {…} TStack TNode T First owner owns the “this” object

16 TStack Example class TStack  stackOwner, TOwner  { TNode  this, TOwner  head; TNode  this, TOwner  head;} class TNode  nodeOwner, TOwner  { TNode  nodeOwner, TOwner  next; TNode  nodeOwner, TOwner  next; T  TOwner  value; T  TOwner  value;} class T  TOwner  {…} TStack TNode T TStack owns the “head” TNode

17 TStack Example class TStack  stackOwner, TOwner  { TNode  this, TOwner  head; TNode  this, TOwner  head;} class TNode  nodeOwner, TOwner  { TNode  nodeOwner, TOwner  next; TNode  nodeOwner, TOwner  next; T  TOwner  value; T  TOwner  value;} class T  TOwner  {…} TStack TNode T The “next” TNode has the same owner as the “this” TNode All TNodes have the same owner

18 TStack Example class TStack  stackOwner, TOwner  { TNode  this, TOwner  head; TNode  this, TOwner  head;} class TNode  nodeOwner, TOwner  { TNode  nodeOwner, TOwner  next; TNode  nodeOwner, TOwner  next; T  TOwner  value; T  TOwner  value;} class Client  clientOwner  { TStack  this, this  s1; TStack  this, this  s1; TStack  this, world  s2; TStack  this, world  s2; TStack  world, world  s3; TStack  world, world  s3;} TStack TNode T s1 is an encapsulated stack with encapsulated elements Client

19 TStack Example class TStack  stackOwner, TOwner  { TNode  this, TOwner  head; TNode  this, TOwner  head;} class TNode  nodeOwner, TOwner  { TNode  nodeOwner, TOwner  next; TNode  nodeOwner, TOwner  next; T  TOwner  value; T  TOwner  value;} class Client  clientOwner  { TStack  this, this  s1; TStack  this, this  s1; TStack  this, world  s2; TStack  this, world  s2; TStack  world, world  s3; TStack  world, world  s3;} TStack TNode T s2 is an encapsulated stack with public elements Client world

20 TStack Example class TStack  stackOwner, TOwner  { TNode  this, TOwner  head; TNode  this, TOwner  head;} class TNode  nodeOwner, TOwner  { TNode  nodeOwner, TOwner  next; TNode  nodeOwner, TOwner  next; T  TOwner  value; T  TOwner  value;} class Client  clientOwner  { TStack  this, this  s1; TStack  this, this  s1; TStack  this, world  s2; TStack  this, world  s2; TStack  world, world  s3; TStack  world, world  s3;} TStack TNode T s3 is a public stack with public elements world

21 TStack Example class TStack  stackOwner, TOwner  { TNode  this, TOwner  head; TNode  this, TOwner  head;} class TNode  nodeOwner, TOwner  { TNode  nodeOwner, TOwner  next; TNode  nodeOwner, TOwner  next; T  TOwner  value; T  TOwner  value;} class Client  clientOwner  { TStack  this, this  s1; TStack  this, this  s1; TStack  this, world  s2; TStack  this, world  s2; TStack  world, world  s3; TStack  world, world  s3; TStack  world, this  s4; // illegal TStack  world, this  s4; // illegal} TStack TNode T Other owners must be same as or more public than first owner [CD02] This constraint is necessary to enforce encapsulation with subtyping

22 class Client  cOwner, sOwner, tOwner  where (sOwner <= tOwner) { … TStack  sOwner, tOwner  head; TStack  sOwner, tOwner  head;} Constraints on Owners Programmers can constrain owners using where clauses This is legal only if tOwner is same as or more public than sOwner

23 Iterators Consider an Iterator i over Stack s Consider an Iterator i over Stack s If i is encapsulated within s If i is encapsulated within s  Then i cannot be used outside s If i is not encapsulated within s If i is not encapsulated within s  Then i cannot access representation of s TStack TStackEnum

24 Solution Use inner classes Use inner classes Gives desired access to representation Gives desired access to representation Yet, satisfies our modularity goal Yet, satisfies our modularity goal

25 class TStack  stackOwner, TOwner  { TNode  this, TOwner  head; TNode  this, TOwner  head; …. …. class TStackEnum  enumOwner, TOwner  implements class TStackEnum  enumOwner, TOwner  implements TEnum  enumOwner, TOwner  { TEnum  enumOwner, TOwner  { TNode  TStack.this, TOwner  current = TStack.this.head; TNode  TStack.this, TOwner  current = TStack.this.head; …. …. }} Iterators Inner class objects can access rep of outer class objects TStack TStackEnum

26 class TStack  stackOwner, TOwner  { TNode  this, TOwner  head; TNode  this, TOwner  head; …. …. class TStackEnum  enumOwner, TOwner  implements class TStackEnum  enumOwner, TOwner  implements TEnum  enumOwner, TOwner  {…} TEnum  enumOwner, TOwner  {…} TStackEnum  enumOwner, TOwner  elements  enumOwner  ( ) TStackEnum  enumOwner, TOwner  elements  enumOwner  ( ) where (enumOwner <= TOwner) {…} where (enumOwner <= TOwner) {…}} Iterators TStack TStackEnum

27 Ownership Types for Encapsulation If an object owns objects it depends on If an object owns objects it depends on Then type system enforces encapsulation Then type system enforces encapsulation  If v is inside s and o is outside  Then o cannot access v  Unless o is inner class object of s v ~ ~ so

28 class TStack  stackOwner, TOwner  { TNode  this, TOwner  head; TNode  this, TOwner  head; … T  TOwner  pop() writes (this) { T  TOwner  pop() writes (this) { if (head == null) return null; if (head == null) return null; T  TOwner  value = head.value(); T  TOwner  value = head.value(); head = head.next(); head = head.next(); return value; return value; }} Effects Clauses Methods can specify read and write effects reads(x) means method can read x and its encapsulated objects writes(x) means method can read/write x and its encapsulated objects

29 Related Work Types augmented with owners Types augmented with owners  Clarke, Potter, Noble ( OOPSLA ’98 ) Support for subtyping Support for subtyping  Clarke, Drossopoulou ( OOPSLA ’02 ) Owners combined with effects clauses Owners combined with effects clauses  Boyapati, Rinard ( OOPSLA ’01 )

30 Summary Ownership types capture dependencies Ownership types capture dependencies Extension for inner class objects allows iterators and wrappers Extension for inner class objects allows iterators and wrappers Approach provides expressive power, yet ensures modular reasoning Approach provides expressive power, yet ensures modular reasoning Effects clauses enhance modular reasoning Effects clauses enhance modular reasoning

31 Applications Safe upgrades in persistent object stores Safe upgrades in persistent object stores Preventing data races and deadlocks Preventing data races and deadlocks  Boyapati, Lee, Rinard ( OOPSLA ’01 ) ( OOPSLA ’02 ) Safe region-based memory management Safe region-based memory management  Boyapati, Salcianu, Beebee, Rinard ( MIT ’02 ) Program understanding Program understanding  Aldrich, Kostadinov, Chambers ( OOPSLA ’02 )

32 Upgrades in Persistent Object Stores Persistent Object Stores store objects Persistent Object Stores store objects Persistent Root

33 Upgrades in Persistent Object Stores Objects are accessed within transactions Objects are accessed within transactions  Transactions support modular reasoning in spite of concurrency and failures Persistent Root

34 Uses of Upgrades Upgrades are needed to Upgrades are needed to  Correct errors  Improve performance  Meet changing requirements Upgrades can be Upgrades can be  Compatible or incompatible  Upgrades must be complete Encapsulation enables safe upgrades Encapsulation enables safe upgrades

35 Defining an Upgrade An upgrade is a set of class-upgrades An upgrade is a set of class-upgrades  Upgrades must be complete A class upgrade is A class upgrade is  old-class, new-class, TF   old-class, new-class, TF  TF: old-class  new-class TF: old-class  new-class  TF changes representation of objects  System preserves identity of objects

36 Executing an Upgrade Requires: transforming all old-class objects Requires: transforming all old-class objects Goal: Don’t interfere with applications Goal: Don’t interfere with applications  Don’t stop the world Goal: Be efficient in space and time Goal: Be efficient in space and time  Don’t copy the database

37 Solution: Lazy, Just in Time Applications continue to run Applications continue to run Objects are transformed just before first access Objects are transformed just before first access Upgrades can run in parallel Upgrades can run in parallel

38 Desired Semantics Upgrades appear to run when installed Upgrades appear to run when installed  Serialized before all later application transactions Upgrades appear to run in upgrade order Upgrades appear to run in upgrade order Within an upgrade, transforms run as if each were the first to run Within an upgrade, transforms run as if each were the first to run

39 Related Work PJama: Atkinson, Dmitriev, Hamilton ( POS ’ 00 ) PJama: Atkinson, Dmitriev, Hamilton ( POS ’ 00 ) Orion: Banerjee, Kim, Kim, Korth ( Sigmod ’ 87 ) Orion: Banerjee, Kim, Kim, Korth ( Sigmod ’ 87 ) O2: Deux et al ( IEEE TKDE ’ 90 ) O2: Deux et al ( IEEE TKDE ’ 90 ) OTGen: Lerner, Habermann ( OOPSLA ’ 90 ) OTGen: Lerner, Habermann ( OOPSLA ’ 90 ) Gemstone: Penney, Stein ( OOPSLA ’ 87 ) Gemstone: Penney, Stein ( OOPSLA ’ 87 )

40 How System Works Objects are transformed just before first access Objects are transformed just before first access  Interrupt the application  Run earliest pending transform  Transform runs in its owns transaction Application continues after transform commits Application continues after transform commits Transforms can be interrupted too Transforms can be interrupted too

41 Example …;U1;A1;TF1(x);A2;… U1 is installed A1 commits A2 accesses x and is interrupted TF1(x) commits A2 commits

42 Example …;U1;A1;TF1(x);A2;… U1 is installed A1 commits A2 accesses x and is interrupted TF1(x) commits A2 commits Suppose A1 modifies z and TF1(x) uses z

43 Example …;U1;A1;TF1(x);A2;TF1(y);A3; … U1 is installed A1 commits A2 accesses x and is interrupted TF1(x) commits A2 commits A3 accesses y and is interrupted TF1(y) commits A3 commits

44 Example …;U1;A1;TF1(x);A2;TF1(y);A3; … U1 is installed A1 commits A2 accesses x and is interrupted TF1(x) commits A2 commits A3 accesses y and is interrupted TF1(y) commits A3 commits Suppose TF1(y) uses x

45 Insuring Correct Behavior S1: TF(x) only accesses objects x owns S1: TF(x) only accesses objects x owns  Statically enforced by type system

46 Insuring Correct Behavior S1: TF(x) only accesses objects x owns S1: TF(x) only accesses objects x owns  Statically enforced by type system S2: x is transformed before objects x owns S2: x is transformed before objects x owns  No access to owned objects from outside  Shared access to owned objects from inner class objects (e.g., iterator) s v i

47 Insuring Correct Behavior S1: TF(x) only accesses objects x owns S1: TF(x) only accesses objects x owns S2: x is transformed before objects x owns S2: x is transformed before objects x owns Plus basic lazy scheme Plus basic lazy scheme  Applications don’t interfere with transforms  Transforms of unrelated objects don’t interfere  Transforms of related objects run in proper order (owner before owned)

48 Modular Reasoning S1: TF(x) only accesses objects x owns S1: TF(x) only accesses objects x owns S2: x is transformed before objects x owns S2: x is transformed before objects x owns Plus basic lazy scheme Plus basic lazy scheme Ensures modular reasoning: can reason about TF(x) as an extra method of x’s class Ensures modular reasoning: can reason about TF(x) as an extra method of x’s class

49 Conclusions Modular reasoning is key Modular reasoning is key Ownership types support modular reasoning Ownership types support modular reasoning Software upgrades benefit too Software upgrades benefit too

50 Ownership Types for Object Encapsulation Barbara Liskov Chandrasekhar Boyapati Liuba Shrira Laboratory for Computer Science Massachusetts Institute of Technology {liskov, chandra, liuba}@lcs.mit.edu

51 class IntVector { int size() reads (this) {…} … int size() reads (this) {…} …} class IntStack { IntVector  this  vec; IntVector  this  vec; void push(int x) writes (this) {…} … void push(int x) writes (this) {…} …} void m (IntStack s, IntVector v) writes (s) reads (v) where !(v <= s) !(s <= v) { where !(v <= s) !(s <= v) { int n = v.size(); s.push(3); assert( n == v.size() ); int n = v.size(); s.push(3); assert( n == v.size() );} Example of Local Reasoning Is the condition in the assert true?

52 Example of Local Reasoning s is not encapsulated in v, and v is not encapsulated in s class IntVector { int size() reads (this) {…} … int size() reads (this) {…} …} class IntStack { IntVector  this  vec; IntVector  this  vec; void push(int x) writes (this) {…} … void push(int x) writes (this) {…} …} void m (IntStack s, IntVector v) writes (s) reads (v) where !(v <= s) !(s <= v) { where !(v <= s) !(s <= v) { int n = v.size(); s.push(3); assert( n == v.size() ); int n = v.size(); s.push(3); assert( n == v.size() );}

53 Example of Local Reasoning size only reads v and its encapsulated objects push only writes s and its encapsulated objects class IntVector { int size() reads (this) {…} … int size() reads (this) {…} …} class IntStack { IntVector  this  vec; IntVector  this  vec; void push(int x) writes (this) {…} … void push(int x) writes (this) {…} …} void m (IntStack s, IntVector v) writes (s) reads (v) where !(v <= s) !(s <= v) { where !(v <= s) !(s <= v) { int n = v.size(); s.push(3); assert( n == v.size() ); int n = v.size(); s.push(3); assert( n == v.size() );}

54 Example of Local Reasoning So size and push cannot interfere So the condition in the assert must be true class IntVector { int size() reads (this) {…} … int size() reads (this) {…} …} class IntStack { IntVector  this  vec; IntVector  this  vec; void push(int x) writes (this) {…} … void push(int x) writes (this) {…} …} void m (IntStack s, IntVector v) writes (s) reads (v) where !(v <= s) !(s <= v) { where !(v <= s) !(s <= v) { int n = v.size(); s.push(3); assert( n == v.size() ); int n = v.size(); s.push(3); assert( n == v.size() );}


Download ppt "Ownership Types for Object Encapsulation Barbara Liskov Chandrasekhar Boyapati Liuba Shrira Laboratory for Computer Science Massachusetts Institute of."

Similar presentations


Ads by Google