View
221
Download
1
Tags:
Embed Size (px)
Citation preview
External Uniqueness Presented by Nir Atias
Dave ClarkeTobias 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
Borrowing Operation
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 { unique Bus bus; this ServerSocket ss; void accept() { while (true) { unique Socket s = ss.accept(); borrow bus as <bo> b { b.add(new unique Client(s--)); } } } }
class Client { owner Bus bus; unique Socket s;
Client( unique Socket s ) { this.s = s--; } }
class Bus { this ClientList clients;
void add( unique Client 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