<div class="socmaildefaultfont" dir="ltr" style="font-family:Arial;font-size:10.5pt" ><div dir="ltr" ><div dir="ltr" >class Collection<any T> {<br> private __SS Collection<T> emptyCollection = …<br> // ACC_SS field emptyCollection : ParamType[Collection, TypeVar[T]]<br><br> private __SS Collection<T> emptyCollection() { return emptyCollection; }<br> ACC_SS emptyCollection()ParamType[Collection, TypeVar[T]] {<br> getstatic ParamType[Collection, TypeVar[T]].emptyCollection : ParamType[Collection, TypeVar[T]]]<br> areturn<br> }</div>
<div dir="ltr" ><div dir="ltr" > </div>
<div dir="ltr" >Based on the example above, I think we need to be more explicit about how the <clinit> method is handled.</div></div>
<div dir="ltr" > </div>
<div dir="ltr" >There are really two different sets of statics that need to be handled by the class initialization: </div>
<div dir="ltr" >A) common statics (shared across all instantiations)</div>
<div dir="ltr" >B) specialized statics</div>
<div dir="ltr" >In addition to the statics, there is also common (and maybe specialized?) code that is run as part of <clinit>.</div>
<div dir="ltr" > </div>
<div dir="ltr" >Where will the initialization code for both kinds of statics be? The existing <clinit> method?</div>
<div dir="ltr" > </div>
<div dir="ltr" >If the specializations re-run the full <clinit> method, they will reset the statics that may have already been defined (!!). Other system invariants may be disturbed (!!) as users are free to put pretty much any code in static { ... } block.</div>
<div dir="ltr" > </div>
<div dir="ltr" >There needs to be some way to partition the code between common (<clinit>) and specialized (<sclint>). If the specializations have a new method <sclint> that only initializes the ACC_SS statics we have the following options:</div>
<div dir="ltr" > </div>
<div dir="ltr" >A) Specializer renames <sclint> to <clinit> in the specialized classes and removes the original <clinit> from specialized classes. The erased class <clinit> handles both common and the erased specialized statics and is called under the same rules as today.</div>
<div dir="ltr" > </div>
<div dir="ltr" >B) Specialized classes call <sclinit> and ignore <clinit>. Common statics in <clinit> get initialized when referenced through the erased Collection<_> class. (This is the same as A but has the VM do the work)</div>
<div dir="ltr" > </div>
<div dir="ltr" >Similarly, we can also modify the initialization order to ensure that the erased class (<clinit>) is initialized before the specialized class (<sclint>).</div>
<div dir="ltr" > </div>
<div dir="ltr" >When using *static, are we only discussing {get,put}? Or is this also proposing invokestatic changes to allow specialized static methods?</div>
<div dir="ltr" > </div>
<div dir="ltr" >All of the technical details aside, is this something we really want to expose to the users? They're going to have a hard time understanding why Foo<int> (or Foo<ValueType) gets specialized statics while Foo<String> & Foo<Bar> share the erased version.</div>
<div dir="ltr" > </div>
<div dir="ltr" >--<br>Bjørn Vårdal</div></div>
<div dir="ltr" > </div>
<blockquote data-history-content-modified="1" dir="ltr" style="border-left:solid #aaaaaa 2px; margin-left:5px; padding-left:5px; direction:ltr; margin-right:0px" >----- Original message -----<br>From: Brian Goetz <brian.goetz@oracle.com><br>Sent by: "valhalla-spec-experts" <valhalla-spec-experts-bounces@openjdk.java.net><br>To: valhalla-spec-experts@openjdk.java.net<br>Cc:<br>Subject: Classes, specializations, and statics<br>Date: Mon, Feb 15, 2016 1:11 PM<br>
<div><font face="Menlo" >M3 leaves us in a position to check off one of the outstanding issues, which is that of specialization-specific statics. </font></div>
<div> </div>
<div><font face="Menlo" >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. </font></div>
<div> </div>
<div><font face="Menlo" >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.) </font></div>
<div> </div>
<div><font face="Menlo" >The following program would be sensitive to this distinction:</font></div>
<div> </div>
<div><font face="Menlo" >class Foo<any T> {</font></div>
<div><font face="Menlo" > static int count;</font></div>
<div> </div>
<div><font face="Menlo" > public Foo() { ++count; }</font></div>
<div><font face="Menlo" >}</font></div>
<div> </div>
<div><font face="Menlo" >new Foo<String>();</font></div>
<div><font face="Menlo" >new Foo<Number>();</font></div>
<div> </div>
<div><font face="Menlo" >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. </font></div>
<div> </div>
<div><font face="Menlo" >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. </font></div>
<div> </div>
<div> </div>
<div><font face="Menlo" >The Problem</font></div>
<div><font face="Menlo" >-----------</font></div>
<div> </div>
<div><font face="Menlo" >Java code frequently uses tricks like the following, that exploit the assumption of erasure: </font></div>
<div> </div>
<div><font face="Menlo" >// Cached instance of an empty collection</font></div><font face="Menlo" >private static final Collection<?> c = new EmptyCollection<?>();<br><br>// Factory method that dispenses the cached empty collections, suitably casted</font>
<div><font face="Menlo" >public static<T> Collection<T> emptyCollection() { return (Collection<T>) c; }<br><br>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. <br><br>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. </font></div>
<div> </div>
<div> </div>
<div><span style="font-family: Menlo;" >Extending Statics to Specializations</span></div>
<div><span style="font-family: Menlo;" >------------------------------------</span></div>
<div> </div>
<div><font face="Menlo" >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.) </font></div>
<div> </div>
<div><font face="Menlo" >The existing prototype places s</font><span style="font-family: Menlo;" >tatic members of Foo<any T> on the erased species Class[Foo], and </span><span style="font-family: Menlo;" >translates access to static member m of Foo<any T> as:</span></div>
<div> </div>
<div><font face="Menlo" > xxxstatic Class[Foo].m</font></div>
<div> </div>
<div><font face="Menlo" >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. </font></div>
<div> </div>
<div><font face="Menlo" >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. </font></div>
<div> </div>
<div><font face="Menlo" >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. </font></div>
<div> </div>
<div><font face="Menlo" >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. </font></div>
<div> </div>
<div><font face="Menlo" >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. </font></div>
<div> </div>
<div> </div>
<div><font face="Menlo" >Example:<br><br>class Collection<any T> {<br> private __SS Collection<T> emptyCollection = …<br> // ACC_SS field emptyCollection : ParamType[Collection, TypeVar[T]]<br><br> private __SS Collection<T> emptyCollection() { return emptyCollection; }<br> ACC_SS emptyCollection()ParamType[Collection, TypeVar[T]] {<br> getstatic ParamType[Collection, TypeVar[T]].emptyCollection : ParamType[Collection, TypeVar[T]]]<br> areturn<br> }<br><br>When we specialize Collection<int>, the field type, method return type, etc, will all collapse to Collection<int> by the existing mechanisms.</font></div>
<div> </div>
<div> </div></blockquote>
<div dir="ltr" > </div></div><BR>