Classes, specializations, and statics

MacGregor, Duncan (GE Energy Connections) duncan.macgregor at ge.com
Mon Feb 15 18:52:03 UTC 2016


Thanks for posting this Brian, it feels like a good solution that does not
require that specialised statics are tied to the type variable in any
specific way.

I presume this means there¹s likely to be an __SS equivalent to ³<clinit>²
to handle the initialisation of the __SS members? The only pitfall I can
see is the accidental initialisation of statics in that __SS ³<clinit>²,
and I guess that can be covered by suitable compiler warnings.

Regards, Duncan.

On 15/02/2016, 18:11, "valhalla-spec-observers on behalf of Brian Goetz"
<valhalla-spec-observers-bounces at openjdk.java.net on behalf of
brian.goetz at oracle.com> wrote:

>M3 leaves us in a position to check off one of the outstanding issues,
>which is that of specialization-specific statics.
>
>Members of Java classes have historically been divided into static and
>instance members; static members are associated with a class, and
>instance members with an instance of a class.
>
>When Java 5 extended the type system to support multiple TYPES that are
>represented by the same CLASS (e.g., ArrayList<String> and
>ArrayList<Number>), we had a choice; treat static members as belonging to
>the CLASS, or as belonging to the TYPE.  We chose the former, as that was
>consistent with the translation strategy of erasure, and also maximized
>compatibility with existing code.  (When .NET did reified generics, they
>chose the opposite; Foo<Number>.staticMember and Foo<String>.staticMember
>refer different variables.  That¹s also a valid choice.)
>
>The following program would be sensitive to this distinction:
>
>class Foo<any T> {
>    static int count;
>
>    public Foo() { ++count; }
>}
>
>new Foo<String>();
>new Foo<Number>();
>
>In Java, this program would increment the common counter twice; under the
>alternative interpretation, the counters Foo<String>.count and
>Foo<Number>.count would each be incremented once.
>
>Statics in Java work the way they do, and we¹re not proposing we change
>that.  However, once we break the assumption that all instantiations of a
>parameterized type are reference instantiations, we run into some issues
>with existing code idioms.  What follows is a proposed generalization of
>static members in the spirit of Model 3.
>
>
>The Problem
>-----------
>
>Java code frequently uses tricks like the following, that exploit the
>assumption of erasure:
>
>// Cached instance of an empty collection
>private static final Collection<?> c = new EmptyCollection<?>();
>
>// Factory method that dispenses the cached empty collections, suitably
>casted
>public static<T> Collection<T> emptyCollection() { return (Collection<T>)
>c; }
>
>The above trick works because of erasure; a Collection<?> has the same
>representation as a Collection<String>, Collection<Integer>, etc, so we
>can freely cast it about with no loss of type safety.  But once we anyfy
>emptyCollection(), we¹re now hosed; we can¹t cast a Collection<?> to a
>Collection<int>.  This leaves us without a means of coding this common
>idiom, because static members currently are per-class, not
>per-instantiation.
>
>Obviously, the above code must continue to mean what it means today.  But
>we¹d also like a means of extending the above idiom more broadly than
>erased generics.  
>
>
>Extending Statics to Specializations
>------------------------------------
>
>Our current model treats parameterizations of template classes like
>classes; anywhere in the bytecode that one can refer to a Constant_Class,
>one can refer to a Constant_ParameterizedType.  (Whether they are
>actually classes, or more like ³species², is an open question, but
>whatever they are, there¹s a way to write their name in the classfile.)
>
>The existing prototype places static members of Foo<any T> on the erased
>species Class[Foo], and translates access to static member m of Foo<any
>T> as:
>
>    xxxstatic Class[Foo].m
>
>However, we are free to assign meaning to xxxstatic as applied to a
>member reference whose owner is a parameterized type.  Suppose we extend
>the current set of member ownerships from { instance, static } to {
>instance, static, specialization }.  We could then access a
>per-specialization member using xxxstatic on a member reference whose
>owner is a specialization.
>
>The syntactic story is mostly a bikeshed; we¹ll need some token to
>indicate ³per-specialization²; we¹ll use the silly token
>__SpecializationStatic for now.
>
>The access story is simple: static members continue to only be able to
>reference other static members (and not class type variables); __SS
>members can access static members and other __SS members, as well as
>class type variables; instance members can reference static, __SS, and
>instance members. 
>
>The translation / classfile story is simple.  Assume we have a spare flag
>bit (we can synthesize one) for ACC_SPECIALIZATION_STATIC (ACC_SS for
>short.)  Static members are marked with ACC_STATIC; __SS members are
>marked with ACC_SS.  Accesses to static members continue to be translated
>as xxxstatic Class[Foo].m; accesses to __SS members are translated as
>xxxstatic ParamType[Foo,params].m.
>
>The specialization / runtime story is simple.  Static members are treated
>as if they are restricted to the erased species (this is a natural
>choice, since Class[Foo] and ParamType[Foo, erased] describe the same
>class.)  __SS members become static members on each parameterization.
>(Both of these are one-line changes to the existing specializer
>prototype.)  TypeVar constants used in the signature / bodies of __SS
>members are specialized as usual, and just work.
>
>
>Example:
>
>class Collection<any T> {
>   private __SS Collection<T> emptyCollection = Š
>   // ACC_SS field emptyCollection : ParamType[Collection, TypeVar[T]]
>
>   private __SS Collection<T> emptyCollection() { return emptyCollection;
>}
>   ACC_SS emptyCollection()ParamType[Collection, TypeVar[T]] {
>       getstatic ParamType[Collection, TypeVar[T]].emptyCollection :
>ParamType[Collection, TypeVar[T]]]
>       areturn
>   }
>
>When we specialize Collection<int>, the field type, method return type,
>etc, will all collapse to Collection<int> by the existing mechanisms.
>
>



More information about the valhalla-spec-observers mailing list