[JSR308] Unique annotation proposal

Artemus Harper subanark at gmail.com
Thu May 15 14:55:28 EDT 2008


Here is a draft for 4 annotations used to support a Unique annotation. This
document focuses on what the effect of each annotation does in a given
context. Any comments on this would be greatly appreciated. Also any
comments on what you expect a Unique reference to be would be nice.

There are 4 annotations: Escape, NoEscape, ValueIndependent, and Unique.
These are mutually exclusive, except that Unique and Escape may be used
together.


 The type hierarchy is (> is the subtype of operator):

Escape > NoEscape > ValueIndependent

Escape > Unique Escape > ValueIndependent

Unique > Unique Escape

Unique > ValueIndependent

Unique > NoEscape (only as a parameter to a method or when returned)

Unique > Escape (only as a hand off, as described in the Unique section)

Unique may only be assigned to another Unique reference as per a hand off.


 Escape – Escape is the default annotation on types, escape is automatically
annotated on types when another more restrictive annotation cannot be
inferred.


 NoEscape – Indicates that this reference will not leave the scope it is
declared in. NoEscape references may be assigned Escape values.


 NoEscape contexts:


 Local Variable/Parameter: Variables with NoEscape can only be used in
contexts that are NoEscape.


 Method/Constructor receiver: For the method invocation 'this' is NoEscape.


 Method/Constructor: Return values that are NoEscape are either a unique
reference, it is derived from one of the parameters, or is null. When a
method is invoked with any of the parameters or the receiver being Unique,
the return is ValueIndependent. If any of the parameters or the receiver is
NoEscape, the return value is also NoEscape, otherwise the return value is
Escape. This annotation should be used in situations where the method
returns 'this', or is one of the elements passed in, such as a search
method.(Maybe this should be simply disallowed)


 Array element: Array elements may be NoEscape only if the outer element is
also NoEscae. E.g. @NoEscape String[@NoEscape] and @NoEscape String[] are
valid, but String[@NoEscape] is not.


 New: Indicates that the new reference is NoEscape. This can be inferred, so
it is generally not necessary to manually annotate a new reference as
NoEscape.


 Class: Indicates that 'this' never leaves the context of any method call.


 Interfaces: Not allowed.


 Fields: Not allowed. Potentially allowable on NoEscape classes, but the
restrictions on the use of such fields would be very limited. In that only a
Unique reference could access the fields, and such reference would not be a
valid return value, since one of the fields may contain a Unique reference
that is held by a stack ancestor.


 Generic type deceleration: All uses of the type are NoEscape, and allows
the generic type to be annotated as NoEscape (but does not require it). This
is of limited used since fields could not be annotated as NoEscape.


 Literal References: These are Escape references, but may be assigned to
NoEscape.


 Primitives: Not allowed. Primitive values always escape since any code can
use a literal to get their value.


 Unique: A unique reference indicates that in any context where the
reference can be used, it is unique. All other references to the value are
either inaccessible, or are 'dead' via the ValueIndependent annotation.
There can be multiple references to a value where a unique reference exists,
but in those cases the unique reference is inaccessible, and all current
references must become inaccessible before the unique reference becomes
accessible again. This is often the case when a Unique reference is passed
as a NoEscape parameter to a method. For ease of use, null is a legal value
for Unique even though it is not unique. If this behavior is not wanted the
reference can also be annotated with NonNull.


 Hand off - Unique references can also be handed off to other references
(being either Unique or Escape), but doing so disallows further use of that
reference. The hand off is done by making an explicit cast on the reference
to either Unique or Escape, and passing the resulting value to a method or
assigning it to a value. Invoking a method whose receiver is Unique will
also hand off the reference to the method. A hand off cannot occur in a loop
where the reference was declared outside of such loop (or in any such
situation where the hand off could occur more than once for that reference).


 Obtaining a Unique reference – A unique reference is obtained by either
creating an array, or by invoking a constructor whose receiver is NoEscape
or ValueIndepent.


 Contexts:


 Local Variable/Parameter – A unique variable can be passed as a NoEscape
parameter to a method, can be the target of an invocation whose receiver is
NoEscape, or can be returned if the method is Unique. Unique variables
cannot be assigned to other uniquely referenced variables without using a
hand off. Once a hand off is made the variable can only be referenced as
ValueIndependent


 Method/Constructor receiver – 'this' is considered unique and follows the
same restrictions as a local variable.


 Method – Indicates that the return value is unique or null; the callee gets
a Unique reference to the value. Only Unique references and null may be
returned as Unique return values. Not valid for void or primitive return
types.


 Constructor – not valid, since it effectively has a void return type.


 Array element – Array elements may be unique (outer elements need not be
unique). Elements in the array can be set from a unique reference, but array
elements can only be retrieved though
java.util.concurrent.atomic.AtomicReferenceArray.getAndSet method.


 New – A new Unique reference is obtained from invoking a constructor whose
receiver is NoEscape. This can be inferred and need not be directly
annotated.


 Class/Interfaces - Not valid (what would this imply?)


 Fields: The field must be final, and its type must be
java.util.concurrent.atomic.AtomicReference<V> for any type V. Additionally,
it must be initialized though new AtomicReference<V>() or new
AtomicReference<V>(V); subclasses are not allowed. The only method that may
be invoked is "@Unique V getAndSet(@Unique V newValue)". The field may be
referenced in any other way, and cannot be assigned to another reference.


 Generic type definations: A generic type that is annotated with Unique is
constrained to only be gentrified as Unique. If annotated with Unique
Escape, the type may be annotated as either Unique or Escape.


 Literals – Only the null literal may be the value of a Unique reference,
all other values are not allowed.


 ValueIndependent – This annotation indicates that any operation on the
value is independent of its value, except that it may or may not be null.
ValueIndependent is automatically given to Unique references that make the
hand off. Any operation independent of the value of a type is legal on
ValueIndependent.


 ValueIndependent contexts:


 Local Variable/Parameter: Can be tested for null, but not for equality on
other variables. Can invoke final methods if the receiver is
ValueIndependent. Cannot refer to fields unless they are also
ValueIndependent. Primatives cannot be ValueIndependent. Invoking a method
on a ValueIndependent reference cannot be done inside a try block where
ExceptionInInitializerError exception can be caught or any other case where
the value of the reference can affect what the method does (we assume that
any exception can be thrown at anytime in code).


 Method/Constructor receiver – 'this' is considered value independent.


 Method – Indicates that the return value must be treated as
ValueIndependent.


 Constructor – Not valid since constructors effectively have a void return
type.


 ArrayElement – The array elements can only be accessed as ValueIndepenent.


 New – Indicates that the object which is created is value independent. This
can be inferred.


 Class – The class must be final. All method receivers are considered
ValueIndepenent. This annotation is not inherited. Generally, singletons
would be annotated as ValueIndepenent.


 Interface – Not valid, since it is expected that there will be more than
one implementation of an interface.


 Field – The field must be final and treated as value independent.


 Generic type definition – Allows the generic type to be gentrified as
ValueIndependent, but does not require it.


 Literals references – Any literal reference can be assigned to a
ValueIndependent type.


 Primitives – Never valid.




-- 
Artemus Harper
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://lists.csail.mit.edu/pipermail/jsr308/attachments/20080515/155b68e6/attachment.htm 


More information about the JSR308 mailing list