Classes, specializations, and statics
Remi Forax
forax at univ-mlv.fr
Thu Mar 24 23:01:02 UTC 2016
Hi Brian,
you forget Way 3 :)
Way 3: There's still only two placements, static and instance;
"static" means independent of an instance as before, thus i can not be specialized by a type parameter (which is specific to an instance).
Unlike Way 2, static means static and unlike Way 1, there is no need to a new placement, ACC_SPECIES, because there is a new data-structure let's call it TypeValue that allows to create a map which is indexed by a reified type parameter.
class Collections {
private static final TypeValue<List<*>> EMPTY_LIST = new TypeValue<>() {
public List<*> create(Type type) {
return EmptyList.class.newSpecializedInstance(type);
}
});
public static <any T> List<T> emptyList() {
return (List<T>)TYPE_VALUE.get(T.class);
}
}
regards,
Rémi
----- Mail original -----
> De: "Brian Goetz" <brian.goetz at oracle.com>
> À: "Bjorn B Vardal" <bjornvar at ca.ibm.com>, valhalla-spec-experts at openjdk.java.net
> Envoyé: Jeudi 24 Mars 2016 23:00:26
> Objet: Re: Classes, specializations, and statics
>
> I think there's two ways to think about "specialized statics" at the VM
> level; how you think about it conditions which way you're inclined to go.
>
> Way 1: This is a new thing; we used to have placements for "static" and
> "instance", and now we have three placements: static, instance, and
> specialization. We add a new bit (ACC_SPECIES), and define new bytecode
> behaviors for members with the SPECIES bit set.
>
> Way 2: There's still only two placements, static and instance;
> per-specialization static is just the natural reinterpretation of
> "static" in the face of a many-to-one relationship between source
> classes and runtime classes. What we used to think of static really is
> the weird case, which we can model as "new static, but restricted (using
> "where" restriction) to the all-erased specialization."
>
> Both ways are 100% compatible with existing generic sources and
> classfiles. Way 2 (which seems more natural to me, and also means we
> don't have to invent a new thing at the VM level) exploits the
> requirement that Constant_Class[Foo] and Constant_ParamType[Foo, erased]
> *must* describe the same runtime entity.
>
> With Way 2, we still (probably) have a new concept at the language
> level, which governs whether the so-described member is a member of all
> parameterizations, or only the all-erased one, but this gets compiled
> away. This matches up with our treatment of erasure; it is the choice
> of the language compiler to choose erased generics or reified, and Java
> chooses to erase some parameterizations but not all.
>
> .NET chooses Way 2 in the extreme; static members are not shared across
> specializations at all, since they have no notion of erasure.
> Compatibility wouldn't let us go that far; existing statics are shared
> across all erased parameterizations, so they would need to remain so.
>
> On 3/18/2016 5:01 PM, Bjorn B Vardal wrote:
> > > I wonder if it's not better to have a class like ThreadLocal or
> > ClassValue that
> > > represents a constant that can be different depending on the
> > specialization.
> > That solution seems possible - we could implement
> > specialization-specific statics as a static Map<Class<?>, Foo<?>>,
> > where the type parameter is the key and "specialized static" is the
> > value. However, it would be slower than compiling to static access.
> > Are there other use cases that make specialized statics necessary? So
> > far we have empty collection, which can be implemented using the map.
> > State of the Specialization from Dec 2014 mentioned layers - are
> > specialized statics a step along the path to layers? Will a
> > SpecializedValue map for specialized statics look like an
> > afterthought if we go the rest of the way to layers?
> > --
> > Bjørn Vårdal
> >
> > ----- Original message -----
> > From: Remi Forax <forax at univ-mlv.fr>
> > To: Valhalla Expert Group Observers
> > <valhalla-spec-observers at openjdk.java.net>
> > Cc: Bjorn B Vardal/Ottawa/IBM at IBMCA, Brian Goetz
> > <brian.goetz at oracle.com>
> > Subject: Re: Classes, specializations, and statics
> > Date: Tue, Feb 23, 2016 2:57 PM
> > I wonder if it's not better to have a class like ThreadLocal or
> > ClassValue that represents a constant that can be different
> > depending on the specialization.
> >
> > Rémi
> >
> > ----- Mail original -----
> > > De: "Brian Goetz" <brian.goetz at oracle.com>
> > > À: "Bjorn B Vardal" <bjornvar at ca.ibm.com>
> > > Cc: valhalla-spec-experts at openjdk.java.net
> > > Envoyé: Mardi 23 Février 2016 01:23:16
> > > Objet: Re: Classes, specializations, and statics
> > >
> > > It's possible that there could be multiple "ssinit" methods, each
> > > restricted to specific parameterizations (just like any other
> > restricted
> > > method), but in general, the "ssinit" method can be specialized just
> > > like any other method. So what I envision (in the absence of
> > > initialization of conditional members) is possibly two such
> > methods; one
> > > that is specializable (corresponding to _SS members) and one that is
> > > not, restricted to the erased parameterization (corresponding to
> > > traditional statics.)
> > >
> > >
> > >
> > > On 2/22/2016 4:11 PM, Bjorn B Vardal wrote:
> > > > I think we're on the same page regarding specialized <clinit>.
> > > > - The JVM will be handed multiple <clinit> partial methods,
> > and the
> > > > specializer will take care of selecting the appropriate
> > <clinit> for
> > > > each specialization.
> > > > - The erased <clinit> will contain the non-specialized static
> > > > initialization code, which ensures that it only runs once.
> > > > - The erased <clinit> will always run before the first
> > specialization
> > > > <clinit>.
> > > > - The Java syntax is still up for discussion.
> > > > > I think this is mostly a matter of coming up with the right
> > syntax,
> > > > which makes it clear that statics can be per-class or
> > > > per-specialization. There are a whole pile of related
> > > > specialization-related syntax issues, I'll try to get them all
> > in one
> > > > place.
> > > > I don't think the problem will be to make it clear that
> > statics can be
> > > > per-class or per-specialization, but rather why some
> > parameterizations
> > > > (which to the user are synonymous with specializations) don't
> > appear
> > > > to have specialized statics. Do we want to put erasure in the
> > face of
> > > > users like this? It seems better to let the users deal purely with
> > > > parameterizations, and we let specialization and erasure be
> > > > implementation details.
> > > > --
> > > > Bjørn Vårdal
> > > >
> > > > ----- Original message -----
> > > > From: Brian Goetz <brian.goetz at oracle.com>
> > > > To: Bjorn B Vardal/Ottawa/IBM at IBMCA,
> > > > valhalla-spec-experts at openjdk.java.net
> > > > Cc:
> > > > Subject: Re: Classes, specializations, and statics
> > > > Date: Thu, Feb 18, 2016 7:55 PM
> > > >
> > > >
> > > >> Based on the example above, I think we need to be more
> > explicit
> > > >> about how the <clinit> method is handled.
> > > >> There are really two different sets of statics that need
> > to be
> > > >> handled by the class initialization:
> > > >> A) common statics (shared across all instantiations)
> > > >> B) specialized statics
> > > >> In addition to the statics, there is also common (and maybe
> > > >> specialized?) code that is run as part of <clinit>.
> > > >
> > > > There is a reasonable model to collapse these back into one
> > > > concept; treat "common statics" as specialized statics on the
> > > > all-erased parameterization, with a <where> clause that
> > restricts
> > > > them to that parameterization. Not clear whether we
> > actually want
> > > > to represent it that way or not, but its a useful mental model
> > > > that doesn't require the creation of a third thing. (Since
> > > > Class[Foo] and ParamType[Foo,erased*] describe the same class,
> > > > this is also fully binary compatible with existing classes.)
> > > >
> > > > Which means we can do a similar thing with <clinit>, if we
> > want.
> > > > I'll wave my hands because we've not yet talked much about
> > > > conditional members, but it basically looks like this:
> > > >
> > > > <where T*=erased*>
> > > > <init>() { /* common static init code */
> > > > /* specializable init code */ }
> > > >
> > > > <init>() { /* specializable init code */ }
> > > >
> > > > Or not.
> > > >> Where will the initialization code for both kinds of
> > statics be?
> > > >> The existing <clinit> method?
> > > >
> > > > We have two choices:
> > > > - have a new <sclinit> block that gets run once per
> > > > specialization, and keep <clinit>
> > > > - merge the two as above, exploiting planned support for
> > > > conditional members
> > > >
> > > > Either way, as you say, we have to ensure that the common init
> > > > runs exactly once.
> > > >> When using *static, are we only discussing {get,put}? Or
> > is this
> > > >> also proposing invokestatic changes to allow specialized
> > static
> > > >> methods?
> > > >
> > > > Methods too.
> > > >> 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.
> > > >
> > > > I think this is mostly a matter of coming up with the right
> > > > syntax, which makes it clear that statics can be per-class or
> > > > per-specialization. There are a whole pile of related
> > > > specialization-related syntax issues, I'll try to get them
> > all in
> > > > one place.
> > > >
> > > >
> > >
> > >
> >
> >
>
>
More information about the valhalla-spec-observers
mailing list