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