1、Ownership Types for Object Encapsulation,Barbara Liskov Chandrasekhar Boyapati Liuba Shrira,Laboratory for Computer Science Massachusetts Institute of Technology liskov, chandra, liubalcs.mit.edu,Outline,Object EncapsulationOwnership TypesUpgrades in Persistent Object Stores,Modular Reasoning,Goal i
2、s local reasoning about correctness Prove a class meets its specification, using only specifications but not code of other classesCrucial when dealing with large programsRequires no interference from code outside the class Objects must be encapsulated,Consider a Set object s implemented using a Vect
3、or object v,Object Encapsulation,v,s,o,Local reasoning about s is possible If objects outside s do not access v That is, if v is encapsulated within s,Encapsulation,In general, all objects that s depends on must be encapsulated within ss depends on x if mutations of x affect behavior of s Leino, Nel
4、son (SCR 00) Detlefs, Leino, Nelson (SRC 98),Examples,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,s,v,Examples,What does no-dups mean? ! e1.equals(e2), for any elements e1 & e2,So set does not depend on elements if elemen
5、ts are immutable,s,v,Iterators and Encapsulation,Iterators require access to representation,Okay if violations of encapsulation limited to the same module,s,v,i,Ownership Types,Goal is to enforce encapsulation statically,s,v,Programmer can declare s owns v System ensures v is encapsulated in s,Owner
6、ship Types,Every object has an owner Owner can be another object or world Ownership relation forms a tree Owner of an object cannot change,world,Ownership Types for Encapsulation,If an object owns objects it depends on Then type system enforces encapsulation If v is inside s and o is outside Then o
7、cannot access v,v,s,o,Ownership Types,world,class TStack TNode head;void push(T value) T pop() class TNode TNode next; T value; class T ,TStack Example (No Owners),head,TStack,TNode,T,TStack Example (With Owners),class TStackstackOwner, TOwner TNodethis, TOwner head; class TNodenodeOwner, TOwner TNo
8、denodeOwner, TOwner next; TTOwner value; class T TOwner ,TStack,TNode,T,Classes are parameterized with owners,TStack Example,class TStackstackOwner, TOwner TNodethis, TOwner head; class TNodenodeOwner, TOwner TNodenodeOwner, TOwner next; TTOwner value; class T TOwner ,TStack,TNode,T,First owner owns
9、 the “this” object,TStack Example,class TStackstackOwner, TOwner TNodethis, TOwner head; class TNodenodeOwner, TOwner TNodenodeOwner, TOwner next; TTOwner value; class T TOwner ,TStack,TNode,T,TStack owns the “head” TNode,TStack Example,class TStackstackOwner, TOwner TNodethis, TOwner head; class TN
10、odenodeOwner, TOwner TNodenodeOwner, TOwner next; TTOwner value; class T TOwner ,TStack,TNode,T,The “next” TNode has the same owner as the “this” TNode All TNodes have the same owner,TStack Example,class TStackstackOwner, TOwner TNodethis, TOwner head; class TNodenodeOwner, TOwner TNodenodeOwner, TO
11、wner next; TTOwner value; class ClientclientOwner TStackthis, this s1;TStackthis, world s2;TStackworld, world s3; ,TStack,TNode,T,s1 is an encapsulated stack with encapsulated elements,Client,TStack Example,class TStackstackOwner, TOwner TNodethis, TOwner head; class TNodenodeOwner, TOwner TNodenode
12、Owner, TOwner next; TTOwner value; class ClientclientOwner TStackthis, this s1;TStackthis, world s2;TStackworld, world s3; ,TStack,TNode,T,s2 is an encapsulated stack with public elements,Client,world,TStack Example,class TStackstackOwner, TOwner TNodethis, TOwner head; class TNodenodeOwner, TOwner
13、TNodenodeOwner, TOwner next; TTOwner value; class ClientclientOwner TStackthis, this s1;TStackthis, world s2;TStackworld, world s3; ,TStack,TNode,T,s3 is a public stack with public elements,world,TStack Example,class TStackstackOwner, TOwner TNodethis, TOwner head; class TNodenodeOwner, TOwner TNode
14、nodeOwner, TOwner next; TTOwner value; class ClientclientOwner TStackthis, this s1;TStackthis, world s2;TStackworld, world s3;TStackworld, 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 s
15、ubtyping,class ClientcOwner, sOwner, tOwner where (sOwner = tOwner) TStacksOwner, 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,Iterators,Consider an Iterator i over Stack s If i is encapsul
16、ated within s Then i cannot be used outside s If i is not encapsulated within s Then i cannot access representation of s,TStack,TStackEnum,Solution,Use inner classesGives desired access to representation Yet, satisfies our modularity goal,class TStackstackOwner, TOwner TNodethis, TOwner head;.class
17、TStackEnumenumOwner, TOwner implementsTEnumenumOwner, TOwner TNodeTStack.this, TOwner current = TStack.this.head; . ,Iterators,Inner class objects can access rep of outer class objects,TStack,TStackEnum,class TStackstackOwner, TOwner TNodethis, TOwner head;.class TStackEnumenumOwner, TOwner implemen
18、tsTEnumenumOwner, TOwner TStackEnum enumOwner, TOwner elements enumOwner ( )where (enumOwner = TOwner) ,Iterators,TStack,TStackEnum,Ownership Types for Encapsulation,If an object owns objects it depends on Then type system enforces encapsulation If v is inside s and o is outside Then o cannot access
19、 v Unless o is inner class object of s,v,s,o,class TStackstackOwner, TOwner TNodethis, TOwner head;TTOwner pop() writes (this) if (head = null) return null;TTOwner value = head.value();head = head.next();return value; ,Effects Clauses,Methods can specify read and write effects reads(x) means method
20、can read x and its encapsulated objects writes(x) means method can read/write x and its encapsulated objects,Related Work,Types augmented with owners Clarke, Potter, Noble (OOPSLA 98)Support for subtyping Clarke, Drossopoulou (OOPSLA 02)Owners combined with effects clauses Boyapati, Rinard (OOPSLA 0
21、1),Summary,Ownership types capture dependenciesExtension for inner class objects allows iterators and wrappers Approach provides expressive power, yet ensures modular reasoningEffects clauses enhance modular reasoning,Applications,Safe upgrades in persistent object storesPreventing data races and de
22、adlocks Boyapati, Lee, Rinard (OOPSLA 01) (OOPSLA 02)Safe region-based memory management Boyapati, Salcianu, Beebee, Rinard (MIT 02)Program understanding Aldrich, Kostadinov, Chambers (OOPSLA 02),Upgrades in Persistent Object Stores,Persistent Object Stores store objects,Persistent Root,Upgrades in
23、Persistent Object Stores,Objects are accessed within transactions Transactions support modular reasoning in spite of concurrency and failures,Persistent Root,Uses of Upgrades,Upgrades are needed to Correct errors Improve performance Meet changing requirementsUpgrades can be Compatible or incompatibl
24、e Upgrades must be completeEncapsulation enables safe upgrades,Defining an Upgrade,An upgrade is a set of class-upgrades Upgrades must be completeA class upgrade is old-class, new-class, TFTF: old-class new-class TF changes representation of objects System preserves identity of objects,Executing an
25、Upgrade,Requires: transforming all old-class objectsGoal: Dont interfere with applications Dont stop the worldGoal: Be efficient in space and time Dont copy the database,Solution: Lazy, Just in Time,Applications continue to runObjects are transformed just before first accessUpgrades can run in paral
26、lel,Desired Semantics,Upgrades appear to run when installed Serialized before all later application transactionsUpgrades appear to run in upgrade orderWithin an upgrade, transforms run as if each were the first to run,Related Work,PJama: Atkinson, Dmitriev, Hamilton (POS 00) Orion: Banerjee, Kim, Ki
27、m, Korth (Sigmod 87) O2: Deux et al (IEEE TKDE 90) OTGen: Lerner, Habermann (OOPSLA 90) Gemstone: Penney, Stein (OOPSLA 87),How System Works,Objects are transformed just before first access Interrupt the application Run earliest pending transform Transform runs in its owns transaction Application co
28、ntinues after transform commitsTransforms can be interrupted too,Example,;U1;A1;TF1(x);A2; U1 is installed A1 commits A2 accesses x and is interrupted TF1(x) commits A2 commits,Example,;U1;A1;TF1(x);A2; U1 is installed A1 commits A2 accesses x and is interrupted TF1(x) commits A2 commitsSuppose A1 m
29、odifies z and TF1(x) uses z,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,Example,;U1;A1;TF1(x);A2;TF1(y);A3; U1 is installed A1 commits A2 accesses x and is interru
30、pted TF1(x) commits A2 commits A3 accesses y and is interrupted TF1(y) commits A3 commits Suppose TF1(y) uses x,Insuring Correct Behavior,S1: TF(x) only accesses objects x owns Statically enforced by type system,Insuring Correct Behavior,S1: TF(x) only accesses objects x owns Statically enforced by
31、type systemS2: 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,Insuring Correct Behavior,S1: TF(x) only accesses objects x owns S2: x is transformed before objects x owns Plus basic lazy sch
32、emeApplications dont interfere with transforms Transforms of unrelated objects dont interfere Transforms of related objects run in proper order (owner before owned),Modular Reasoning,S1: TF(x) only accesses objects x owns S2: x is transformed before objects x owns Plus basic lazy schemeEnsures modul
33、ar reasoning: can reason about TF(x) as an extra method of xs class,Conclusions,Modular reasoning is keyOwnership types support modular reasoningSoftware upgrades benefit too,Ownership Types for Object Encapsulation,Barbara Liskov Chandrasekhar Boyapati Liuba Shrira,Laboratory for Computer Science M
34、assachusetts Institute of Technology liskov, chandra, liubalcs.mit.edu,class IntVector int size() reads (this) class IntStack IntVectorthis vec;void push(int x) writes (this) void m (IntStack s, IntVector v) writes (s) reads (v)where !(v = s) !(s = v) int n = v.size(); s.push(3); assert( n = v.size(
35、) ); ,Example of Local Reasoning,Is the condition in the assert true?,Example of Local Reasoning,s is not encapsulated in v, and v is not encapsulated in s,class IntVector int size() reads (this) class IntStack IntVectorthis vec;void push(int x) writes (this) void m (IntStack s, IntVector v) writes
36、(s) reads (v)where !(v = s) !(s = v) int n = v.size(); s.push(3); assert( n = v.size() ); ,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) class IntStack IntVectorthis vec;void push(int
37、x) writes (this) void m (IntStack s, IntVector v) writes (s) reads (v)where !(v = s) !(s = v) int n = v.size(); s.push(3); assert( n = v.size() ); ,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) class IntStack IntVectorthis vec;void push(int x) writes (this) void m (IntStack s, IntVector v) writes (s) reads (v)where !(v = s) !(s = v) int n = v.size(); s.push(3); assert( n = v.size() ); ,