----- Mail original -----
> De: "Brian Goetz" <[email protected]>
> À: "Remi Forax" <[email protected]>
> Cc: "amber-spec-experts" <[email protected]>
> Envoyé: Dimanche 1 Septembre 2019 20:22:36
> Objet: Re: Record classfile and runtime API

> Thanks Remi; its a good time to revisit this.  The current strategy was a
> stake-in-the-ground, but needs to be refined before we finalize the design, as
> the bootstrap APIs are forever once we do that.
> 
>> The arguments of the bootstrap methods are redundant, you don't need to pass 
>> the
>> record class because the Lookup object contains the record class (you have 
>> the
>> API in Lookup to create an intermediary lookup from a Lookup and a class so 
>> no
>> need to duplicate that information). For the first boostrap methods, the
>> parameter containing "x;y" is due to the fact that a constant method handle 
>> is
>> opaque by default so you can not get the corresponding field name. First, if
>> you have the lookup that have created that object, you can get back the name
>> with a "reveal". But i think here, the problem is that the arguments are the
>> constant method handles and not the constant decriptor (ConstantDec).
> 
> Redundancy in and of itself is not necessarily bad.  Sure, you can get the 
> class
> from the lookup, but then the bootstrap API is not exactly computing the same
> thing.  Maybe that’s OK,  maybe not, but the design should come first, not
> class file compression.

I'm more worried about people trying to use the API in nasty way, by example 
what if the lookup class is not able to see the class you sent as parameter, 
etc.
Avoiding duplication of the informations is a simple yet effective way to avoid 
misuse of the API.

A record = a class + the record attribute. If we pass more information, then 
you are sending more bits than we should.
   

> 
> Personally, I would prefer to have ONE bootstrap for all three methods (for
> example, using the invocation name to describe which method should be linked.)
> Assumed we did that, what should the argument list be?  As you point out,
> specifying the name string as a single string (“x;y”) is a hack, so we should
> probably not do that.  Using reflection during linkage risks trading class
> file clarity for startup performance, which might not be a good trade.  
> There’s
> a lot of ways to slice this, but we want to choose something that works well 
> on
> all the measures.

yes and no, currently each constant pool constant initialization requires an 
upcall from the VM to the Java code that will create the corresponding Java 
object,
if we are using the reflection it's one downcall, then because the bootstrap 
method is inside the JDK, you can cheat and calls the trusted 
Lookup.linkMethodHandleConstant which already has a cache of direct method 
handles.

Otherwise, you can always a constant dynamic as argument of the BSM that will 
resolve all arguments at once, it will be faster than resolving each argument 
one by one.

> 
> If we had a common API, we could have a common meta-model constant that is
> resolved once and passed to all three methods.  Not sure that carries its
> weight, unless the meta-model object were exposed to users as well.

your meta-model is my constant dynamic described above.
And it can be typed as Object because the producer of the meta-model and the 
consumer are both from the same bootstrap class, so they can agree to use a 
class which is not visible to the user.

BTW, this very same argument can be used for avoiding to publish any extractor 
related type at least not until we are not sure of the design,
using Object as type of the extractor you are losing the fast that other 
languages than Java can specify some non Java patterns, but you can always 
publish the API in a later release (the fact that the bootstrap method is 
called as a invoke and not an invokeExact is what make it working).

> 
>> The java.lang.invoke API has currently the limitation that you can not use 
>> the
>> ConstantDesc API to type values of the constant pool.
> 
> And, the code to put JLC constants in the constant pool isn’t there yet either
> (it originally was, but got pulled back waiting for “invoke” support in condy,
> which is coming soon.)

??,
i think i would prefer that it auto-magically work if the corresponding BSM 
type is a ConstantDesc, a kind of target typing, instead of having to have one 
constant dynamic per constant i wanted to see. 

> 
>> Now we have to talk about the reflection API, currently the method that 
>> reflects
>> the attribute Record is Class.getRecordAccessors() that returns an array of
>> Method corresponding to the accessors and there are many things wrong with 
>> this
>> method.
> 
> There are already plans to replace this with a proper reflective object
> (RecordComponent), this is just not done yet.


yes, it's a better idea, have a java.lang.reflect.RecordComponent like there is 
a java.lang.reflect.Field.

> 
>> So first, let's have a method getRecordComponentFields() in java.lang.Class 
>> that
>> returns an array of
> 
> That’s just as bad as returning methods, probably worse (since the fields are
> private.)  Something more abstract is needed.  But the rest of what you say
> should work well with what we’ve got in the works.

it's not bad because a constant desc is not a live representation of a VM data 
structure, given that resolveConstantDesc requires a Lookup, we are fine here.
Anyway, having a dedicated class RecordComponent is better.

> 
>> BTW, why do we need an extractor for a record ? we should not need one 
>> because
>> we can inside the algorithm that create the pattern tree have a if
>> class.isRecord() ? (the same way the serailization is specilized for enums by
>> example).
> 
> Currently, it’s in there so we can prototype the following phase of pattern
> matching, deconstruction patterns on records.  But, even if records go in much
> earlier than deconstruction patterns, having the pattern support in the class
> file now is valuable, as we don’t want to create the problem of “you can use
> deconstruction on records, but you have to recompile your old record 
> classifies
> first.”

There is no issue if you need to get the deconstructor by reflection because 
the reflection code can fill the gap.

Anyway, i kind a like my proposal to have a deconstructor that returns Object 
now and may return a real type in the future.

Rémi

Reply via email to