330 likes | 530 Views
External Uniqueness Presented by Nir Atias. Dave Clarke Tobias Wrigstad. Encapsulation Seminar 2006. What are we doing here. What is uniqueness? Problems with current approaches Forming a solution External Uniqueness Samples & patterns Conclusions Beyond External Uniqueness.
E N D
External Uniqueness Presented by Nir Atias Dave Clarke Tobias Wrigstad Encapsulation Seminar 2006
What are we doing here • What is uniqueness? • Problems with current approaches • Forming a solution • External Uniqueness • Samples & patterns • Conclusions • Beyond External Uniqueness
Uniqueness • Problem • We want to ensure only one reference to an object exists (no aliasing) • Solution • Annotate a reference as unique and restrict operations on that reference • Introduce a mechanism to work with the reference (borrowing)
Problems • Abstraction • Changes to the implementation of an object require changes in its interface • Orthogonality • The operations on borrowed unique references are limited • Definitional • What happens when an object is borrowed
Abstraction • In existing proposals: • Methods are annotated with respect of consuming unique pointers • Islands • Effects systems • Changes in implementation requires changes in signature • Change is propagated in the program
Orthogonality • Borrowing mechanism places restrictions on the borrowed reference • Don’t want the original object to loose its uniqueness property after borrowing has ceased • This implies that borrowed references have their own rules
Definitional • What happens when a reference is borrowed? • Allow both borrowed reference and unique reference, thus weakening reasoning power • Nullify the original reference during borrowing, risk race conditions and NullPointerException • Ensure that when unique reference is used, all aliases and borrowed references are dead.
The Main Idea • Introduce a new type of uniqueness: External Uniqueness • A reference is externally unique if it is the only external reference to an object • Internal aliasing is allowed
Forming a solution • Use ownership types to determine aggregate scope • Ownership types distinguish between the inside and the outside of an object • Ownership types allow reasoning about aggregates • Nullify unique reference while borrowing (simplicity)
Ownership Types • Are you in or out? • Distinction between the inside and outside of an object • An object cannot be accessed from outside of its owner • Owner as permission to access an object • Owners-as-dominators property • owners are on all paths from the root to an object in the object graph
Ownership Types – cont. • Parameterize classes by owners • Additional owner parameters are allowed (owner <* pi ) • this can be used as an owner for owned objects (this <* owner) • An object may refer only to • objects it owns • objects that are owned by its parameters
External Uniqueness • A reference is externally unique if it is the only external reference to an object • In object graph representation, we have dominating edge property • Refine the owners-as-dominators property • The edge is on all paths from the root to an object in the object graph • Allow to move aggregates
Dominating Edge • In red we have the ownership tree • In blue we have the object graph • If a reference is unique then we have dominating edge
Ownership and Uniqueness • unique is part of the type • A unique reference has a movement bound that acts as an owner • If p is the movement bound of a unique reference we will depict the reference as uniquep • Movement bound can change • While regular owner is invariant • Movement bound can be declared by the programmer
Externally Unique References • Movement • Allow destructive read operation • Possibly loosing uniqueness • Cannot assign owner with not enough permissions
Externally Unique References • Borrowing • Unique references can be treated as ordinary references (temporarily) • Type system ensures that when the borrowing has finished no additional references remain • The original reference (or other) is restored to the place from where it was borrowed
So what do we have? • Only one of the following • One active reference • Dominating edge property ensures that there is only one active reference to an object • Internal references are active only while borrowing • Many references with limited scope • Borrowing is limited in scope • Original unique reference is invalidated
Some more info • Constructors are viewed as (almost) regular method calls • Parameters cannot have owner in the type (except as a movement bound) • As a result: this cannot be assigned to an external (pre-existing) object • Methods can be parameterized by owners • Cannot capture argument whose owner is a parameter
Samples Common scenarios & Addressing known issues
Borrowing • Borrowing • Accessing methods and fields requires borrowing • External Uniqueness • The bus is externally unique but have multiple references from owned Clients class Server {uniqueBus bus;this ServerSocket ss;void accept() {while (true) {uniqueSocket s = ss.accept();borrow bus as <bo> b { b.add(new unique Client(s--)); } } } }class Client {ownerBus bus;uniqueSocket s; Client( uniqueSocket s ) {this.s = s--;} }class Bus {this ClientList clients; void add( uniqueClient c ) {this Client current = c--; clients.add(current); current.bus = this;} }
Simulating Borrowing • Owner-polymorphic methods (guarantees not to create heap-level aliases) can be called with unique references class Printer { static <o <* world>void print(o Printable p ) {... }} unique B b; // implements Printableborrow b as <a> b1 { Printer.print<a>(b1); }
Orthogonality • Scoped regions enables construction of temporary heap objects, that referes to existing objects • Existing objects might be unique • No aliasing outside of scope because of deep-ownership class Printer { static <o <* world>void print(o Printable p ) {(a) { // temporary owner a LayoutManager<o> lm; lm = new a LayoutManager<o>(p); lm.addBorder(); lm.print( "....." );} }} unique B b; // implements Printableborrow b as <a> b1 { Printer.print<a>(b1); }
External Initialization • Problematic with ownership types (static owners) • The movement bound changes (downwards in the object graph) class Lexer {this InputStream stream; Lexer( unique InputStream s) { stream = s--; } } void lexerClient() {unique InputStream stream;unique Lexer l; stream = new FileInputStream(file); l = new Lexer(stream--);}
Transfer of Ownership • Important pattern in concurrent programming • Movement-bound of B is D, so no references to A are allowed in B • B can be a complex aggregate class TokenRing {owner TokenRing next;unique Token token; void give() { next.recieve(token--); } void recieve(unique Token tkn) { token = tkn--; }}
Merging Representations • Merging (without copying) linked data structures • Without breaking encapsulation • In the sample: • bh can change while borrowed class Link<data> { data Object data;owner Link<data> next, prev;} class List<data> {unique Link<data> head; void append( owner List<data> other ) {borrow head as <ho> bh { ho Link<data> ohead = other.head--;if( bh==null ) { bh = ohead;} else if( ohead!=null ) { ho Link<data> h = bh;while( h.next != null ) { h = h.next;} h.next = ohead; h.next.prev = h;}}}}
Conclusions • Abstraction • All classes can be used as unique references • Regardless of class declaration • Methods are not annotated with reference consumption information
Conclusions • Orthogonality • Using several mechanism: • Borrowing • Owner polymorphic methods • Scoped regions • After borrowing, a unique reference can be used as a regular reference • No restrictions on borrowed references • No concept of borrowed reference in the language
Conclusions • Definitional • Original reference is nullified • Reinstatement of borrowed value adds power • Prone to race conditions • A better solution • Exists but much more complicated (invalidate the borrowed references when the original is accessed)
Anything else? • Reentrancy • Once borrowed, a unique object can only be reentered from a local (nested) object • Therefore it cannot be reentered from an external object • An object referred to uniquely can only be entered by one thread
Some more… • Object model • Ownership types model IS-PART-OF relationship • All references to an owned object are confined within it owner • Lifetime management • Further work required
Beyond External Uniqueness • Iterator Pattern • Or how to publish an object with knowledge of implementation • Break the encapsulation in a given scope • Inner classes • Package • Primary owners • Exception Handling • How does it fit with ownership types languages? • Static methods
The End Hope you had some fun