Re: Evolving the wrapper classes

2020-06-19 Thread Dan Smith
> On Jun 19, 2020, at 2:44 PM, fo...@univ-mlv.fr wrote:
> 
> If the VM see I as a subtype of Object, there is no need for a 
> Ljava/lang/Integer$val; at all, it's better to have aload/astore/etc to work 
> on I directly.

That's initially somewhat attractive, but think about the implications for 
things like slot size. Primitives and inline objects are really two very 
different things in the current JVM design.

Re: Evolving the wrapper classes

2020-06-19 Thread Dan Smith
> On Jun 19, 2020, at 1:51 PM, fo...@univ-mlv.fr wrote:
> 
> covariant return type
>  interface I {
> int foo();
>  }
>  interface J {
> Object foo();
>  }
>  class A implements I, J {
>int foo();
>  }
> 
> with I.java compiled a long time ago.

Nothing in this proposal changes how these classes are compiled. The following 
methods will exist:

I.foo()I
J.foo()Ljava/lang/Object;
A.foo()I
A.foo()Ljava/lang/Object; // bridge

I think you may be mixed up thinking that we'll sometimes translate 'int' in a 
descriptor to 'Ljava/lang/Integer$val;', but that's not the case. 'I' is 
preferred wherever possible.



Re: Evolving the wrapper classes

2020-06-19 Thread forax
- Mail original -
> De: "daniel smith" 
> À: "Remi Forax" 
> Cc: "Brian Goetz" , "valhalla-spec-experts" 
> 
> Envoyé: Vendredi 19 Juin 2020 21:27:12
> Objet: Re: Evolving the wrapper classes

>> On Jun 19, 2020, at 12:54 PM, Remi Forax  wrote:
>> 
>>> Note that [I and [QInteger$val have the exact same layout, so it is really a
>>> matter of treating the two type names as referring to the same underlying
>>> runtime type.
>> 
>> yes, but at the same time descriptor are matched by name and you need to have
>> the proper descriptor when overriding/implementing a method,
>> so the strategy of blindly replacing every I by QInteger$val; doesn't really
>> work.
>> 
>> Usually the solution is to use bridges but bridges only work with subtyping
>> relationship not equivalence relationship (because you can travel in both
>> direction).
>> I believe we need to bring the forward/bridge-o-matic at the same time we
>> retrofit primitive to inline.
> 
> In the VM this is mostly a verification problem: have a
> '[Qjava/lang/Integer$val;', need a '[I'? You're good! ("Mostly", because there
> is still the matter of ensuring there's a single encoding for both kinds of
> objects, or that the instructions are capable of handling two different
> encodings.)
> 
> I'm not sure we'd get into any situations where a '([I)V' descriptor needs to
> override a '([Qjava/lang/Integer$val)V' descriptor, or vice versa, until we 
> get
> to specialization,

covariant return type
  interface I {
 int foo();
  }
  interface J {
 Object foo();
  }
  class A implements I, J {
int foo();
  }

with I.java compiled a long time ago.

> and then I'm not sure this is any different than other forms
> of bridging. All existing code will continue to use 'I' in its compiled
> descriptors.

if everything is compiled at the same time, there is no issue, otherwise you 
can create a loop.

Rémi


Re: Evolving the wrapper classes

2020-06-19 Thread Dan Smith


> On Jun 19, 2020, at 12:54 PM, Remi Forax  wrote:
> 
>> Note that [I and [QInteger$val have the exact same layout, so it is really a 
>> matter of treating the two type names as referring to the same underlying 
>> runtime type.
> 
> yes, but at the same time descriptor are matched by name and you need to have 
> the proper descriptor when overriding/implementing a method,
> so the strategy of blindly replacing every I by QInteger$val; doesn't really 
> work.
> 
> Usually the solution is to use bridges but bridges only work with subtyping 
> relationship not equivalence relationship (because you can travel in both 
> direction).
> I believe we need to bring the forward/bridge-o-matic at the same time we 
> retrofit primitive to inline.

In the VM this is mostly a verification problem: have a 
'[Qjava/lang/Integer$val;', need a '[I'? You're good! ("Mostly", because there 
is still the matter of ensuring there's a single encoding for both kinds of 
objects, or that the instructions are capable of handling two different 
encodings.)

I'm not sure we'd get into any situations where a '([I)V' descriptor needs to 
override a '([Qjava/lang/Integer$val)V' descriptor, or vice versa, until we get 
to specialization, and then I'm not sure this is any different than other forms 
of bridging. All existing code will continue to use 'I' in its compiled 
descriptors.



Re: Evolving the wrapper classes

2020-06-19 Thread forax
Blindly is perhaps a word too strong, let say we have to come with a plan, a 
good plan, 
and i fail to see how it can work with only the current bridge mechanism we 
have. 

Rémi 

> De: "Brian Goetz" 
> À: "Remi Forax" 
> Cc: "Tobi Ajila" , "valhalla-spec-experts"
> , "valhalla-spec-experts"
> 
> Envoyé: Vendredi 19 Juin 2020 20:59:35
> Objet: Re: Evolving the wrapper classes

>> yes, but at the same time descriptor are matched by name and you need to have
>> the proper descriptor when overriding/implementing a method,
>> so the strategy of blindly replacing every I by QInteger$val; doesn't really
>> work.

> Who said blindly?


Re: Evolving the wrapper classes

2020-06-19 Thread Brian Goetz

I hope to surprise you positively!

On 6/19/2020 3:09 PM, fo...@univ-mlv.fr wrote:
Blindly is perhaps a word too strong, let say we have to come with a 
plan, a good plan,
and i fail to see how it can work with only the current bridge 
mechanism we have.






Re: Evolving the wrapper classes

2020-06-19 Thread Brian Goetz




yes, but at the same time descriptor are matched by name and you need 
to have the proper descriptor when overriding/implementing a method,
so the strategy of blindly replacing every I by QInteger$val; doesn't 
really work.


Who said blindly?



Re: Evolving the wrapper classes

2020-06-19 Thread Remi Forax
> De: "Brian Goetz" 
> À: "Tobi Ajila" 
> Cc: "valhalla-spec-experts" ,
> "valhalla-spec-experts" 
> Envoyé: Vendredi 19 Juin 2020 20:18:09
> Objet: Re: Evolving the wrapper classes

> Zooming out, what we've been trying to do is shake out the places where the 
> JVM
> treats primitives and references differently, and aligning them, so that we 
> are
> able to broaden the approach of "generics erase T to Object" to include 
> inlines
> and primitives. The war cry might be:

> Object is the new Any

> L-World does much of this for inlines, but we don't want to leave primitives 
> out
> in in the cold in the programming model; being able to get good behavior for
> Foo but not the same for Foo would be a missed opportunity to
> provide a uniform programming model. Much of this is either handled by 
> existing
> L-World behavior (e.g., behavior of ==), but this seam is one that needs to be
> covered. We can cover some in the static compiler (conversions between I and
> Qint) but when it comes to arrays, the invariance of arrays would expose our
> tricks, and we'd have to have awful restrictions like "you can't use arrays in
> generics."

> Note that [I and [QInteger$val have the exact same layout, so it is really a
> matter of treating the two type names as referring to the same underlying
> runtime type.
yes, but at the same time descriptor are matched by name and you need to have 
the proper descriptor when overriding/implementing a method, 
so the strategy of blindly replacing every I by QInteger$val; doesn't really 
work. 

Usually the solution is to use bridges but bridges only work with subtyping 
relationship not equivalence relationship (because you can travel in both 
direction). 
I believe we need to bring the forward/bridge-o-matic at the same time we 
retrofit primitive to inline. 

Rémi 

> On 6/19/2020 1:07 PM, Tobi Ajila wrote:

>>> Because arrays have identity (not to mention potentially large copying 
>>> costs),
>>> there is simply no reasonable conversion we can define; any "conversion" 
>>> would
>>> involve copying all the data, changing identity, or both. Just as with the
>>> array subtyping requirements (Point[] <: Point.ref[] <: Object[]), these are
>> > things only the VM can do for us.

>> I suspected that this was likely due to the large cost of converting between
>> `[I` and `[java/lang/Integer$val`. However, I am still a little unclear as to
>> what the motivation is for this. Is this solely for specialized generics?

>> In Dan's examples with `I` and `java/lang/Integer$val`, the only places where
>> conversions are needed are when primitives are used as type parameters or to
>> call instance methods on them, both of which can already be done with 
>> primitive
>> arrays. So in the LW3 - LW20 timeframe would we have any need for these
>> conversions? If so, could you provide some examples?

>> In the case of specialized generics, is the intention that `[I` (and I 
>> suppose
>> `I` as well) will appear in generic code?


Re: Evolving the wrapper classes

2020-06-19 Thread Brian Goetz
Zooming out, what we've been trying to do is shake out the places where 
the JVM treats primitives and references differently, and aligning them, 
so that we are able to broaden the approach of "generics erase T to 
Object" to include inlines and primitives.  The war cry might be:


    Object is the new Any

L-World does much of this for inlines, but we don't want to leave 
primitives out in in the cold in the programming model; being able to 
get good behavior for Foo but not the same for Foo would be 
a missed opportunity to provide a uniform programming model.  Much of 
this is either handled by existing L-World behavior (e.g., behavior of 
==), but this seam is one that needs to be covered.  We can cover some 
in the static compiler (conversions between I and Qint) but when it 
comes to arrays, the invariance of arrays would expose our tricks, and 
we'd have to have awful restrictions like "you can't use arrays in 
generics."


Note that [I and [QInteger$val have the exact same layout, so it is 
really a matter of treating the two type names as referring to the same 
underlying runtime type.


On 6/19/2020 1:07 PM, Tobi Ajila wrote:


> Because arrays have identity (not to mention potentially large 
copying costs), there is simply no reasonable conversion we can 
define; any "conversion" would involve copying all the data, changing 
identity, or both.  Just as with the array subtyping requirements 
(Point[] <: Point.ref[] <: Object[]), these are things only the VM can 
do for us.


I suspected that this was likely due to the large cost of converting 
between `[I` and `[java/lang/Integer$val`. However, I am still a 
little unclear as to what the motivation is for this. Is this solely 
for specialized generics?


In Dan's examples with `I` and `java/lang/Integer$val`, the only 
places where conversions are needed are when primitives are used as 
type parameters or to call instance methods on them, both of which can 
already be done with primitive arrays. So in the LW3 - LW20 timeframe 
would we have any need for these conversions? If so, could you provide 
some examples?


In the case of specialized generics, is the intention that `[I` (and I 
suppose `I` as well) will appear in generic code?






RE: Evolving the wrapper classes

2020-06-19 Thread Tobi Ajila
Thanks for the example Dan, this "Object[] objs = arr; // just like Point[]
<: Object[]" makes it very clear. Brian's response makes more sense to me
now.


> From: Dan Smith 
> To: Tobi Ajila 
> Cc: Brian Goetz , valhalla-spec-experts
> , valhalla-spec-experts
> 
> Date: 2020/06/19 01:32 PM
> Subject: [EXTERNAL] Re: Evolving the wrapper classes
>
>
> > On Jun 19, 2020, at 11:07 AM, Tobi Ajila  wrote:
> >
> > I am still a little unclear as to what the motivation is for this.
> Is this solely for specialized generics?
> >
> > In Dan's examples with `I` and `java/lang/Integer$val`, the only
> places where conversions are needed are when primitives are used as
> type parameters or to call instance methods on them, both of which
> can already be done with primitive arrays. So in the LW3 - LW20
> timeframe would we have any need for these conversions? If so, could
> you provide some examples?
>
> I think it comes down to specialization and subtyping.
>
> Pre-specialization, here's one example that uses subtyping:
>
> int[] arr = { 1 };
> Object[] objs = arr; // just like Point[] <: Object[]
> Object obj = objs[0];
> Integer i = (Integer) obj;
>
> This would compile to something like:
>
> iconst_1
> newarray T_INT
> dup
> iconst_0
> iconst_1
> iastore
> astore_0
>
> aload_0
> astore_1
>
> aload_1
> iconst_0
> aaload
> astore_2
>
> aload_2
> checkcast java/lang/Integer
> astore_3
>
> Going in the other direction—allocating a [Qjava/lang/Integer; and
> then using iaload/iastore on it—may not be necessary unless/until
> the language supports "new T[]" in specialized code, but it
> tentatively makes sense to support now anyway, rather than having to
> come back and fix it up later.
>
> > In the case of specialized generics, is the intention that `[I`
> (and I suppose `I` as well) will appear in generic code?
>
> If you mean "can '[' be specialized to '[I'?", the answer is no.
> The primitive types cannot act as type arguments.


Re: Evolving the wrapper classes

2020-06-19 Thread Dan Smith
PSA: this thread has been polluted with the address:

valhalla-spec-experts 

Which just generates admin notifications. Please delete that address from any 
replies. :-)

Re: Evolving the wrapper classes

2020-06-19 Thread Dan Smith


> On Jun 19, 2020, at 11:07 AM, Tobi Ajila  wrote:
> 
> I am still a little unclear as to what the motivation is for this. Is this 
> solely for specialized generics?
> 
> In Dan's examples with `I` and `java/lang/Integer$val`, the only places where 
> conversions are needed are when primitives are used as type parameters or to 
> call instance methods on them, both of which can already be done with 
> primitive arrays. So in the LW3 - LW20 timeframe would we have any need for 
> these conversions? If so, could you provide some examples?

I think it comes down to specialization and subtyping.

Pre-specialization, here's one example that uses subtyping:

int[] arr = { 1 };
Object[] objs = arr; // just like Point[] <: Object[]
Object obj = objs[0];
Integer i = (Integer) obj;

This would compile to something like:

iconst_1
newarray T_INT
dup
iconst_0
iconst_1
iastore
astore_0

aload_0
astore_1

aload_1
iconst_0
aaload
astore_2

aload_2
checkcast java/lang/Integer
astore_3

Going in the other direction—allocating a [Qjava/lang/Integer; and then using 
iaload/iastore on it—may not be necessary unless/until the language supports 
"new T[]" in specialized code, but it tentatively makes sense to support now 
anyway, rather than having to come back and fix it up later.

> In the case of specialized generics, is the intention that `[I` (and I 
> suppose `I` as well) will appear in generic code?

If you mean "can '[' be specialized to '[I'?", the answer is no. The 
primitive types cannot act as type arguments.

RE: Evolving the wrapper classes

2020-06-19 Thread Tobi Ajila


> Because arrays have identity (not to mention potentially large copying
costs), there is simply no reasonable conversion we can define; any
"conversion" would involve copying all the data, changing identity, or
both.  Just as with the array subtyping requirements (Point[] <: Point.ref
[] <: Object[]), these are things only the VM can do for us.

I suspected that this was likely due to the large cost of converting
between `[I` and `[java/lang/Integer$val`. However, I am still a little
unclear as to what the motivation is for this. Is this solely for
specialized generics?

In Dan's examples with `I` and `java/lang/Integer$val`, the only places
where conversions are needed are when primitives are used as type
parameters or to call instance methods on them, both of which can already
be done with primitive arrays. So in the LW3 - LW20 timeframe would we have
any need for these conversions? If so, could you provide some examples?

In the case of specialized generics, is the intention that `[I` (and I
suppose `I` as well) will appear in generic code?



Re: Evolving the wrapper classes

2020-06-19 Thread Brian Goetz
> Given your examples can we assume that the JVM will never need to do an 
> implicit `Qjava/lang/Integer$val;` to `I` conversion? And these will always 
> be explicit conversions performed by javac?
> 

Correct.

> > - The type [I is considered by the verifier to be equivalent to 
> > [java/lang/Integer$val. Array operations (aaload, iaload, etc.) support 
> > this.
> 
> Could you please explain the motivation behind this? Specifically, in which 
> cases are iaload and aaload operations both performed on `[I` ? 
> 
> If `I` and `Qjava/lang/Integer$val;` will require explicit javac conversions, 
> shouldn't `[I` and `[java/lang/Integer$val` also?
> 

Because arrays have identity (not to mention potentially large copying costs), 
there is simply no reasonable conversion we can define; any “conversion” would 
involve copying all the data, changing identity, or both.  Just as with the 
array subtyping requirements (Point[] <: Point.ref[] <: Object[]), these are 
things only the VM can do for us.  




RE: Evolving the wrapper classes

2020-06-19 Thread Tobi Ajila
Hi Dan S.

>>> - Where necessary (depending on the operations being performed), the
compiler generates conversions between 'I' and 'java/lang/Integer$val'. 'I'
is preferred wherever possible.
>>
>> We have to use QInteger$val whenever we use int as a type parameter, the
rest of the time, we can use I.
...
> (Note that none of these conversions are "boxing" or "unboxing". They're
strictly compilation artifacts. It may be useful to come up with a new word
for them.)

Given your examples can we assume that the JVM will never need to do an
implicit `Qjava/lang/Integer$val;` to `I` conversion? And these will always
be explicit conversions performed by javac?

> - The type [I is considered by the verifier to be equivalent to
[java/lang/Integer$val. Array operations (aaload, iaload, etc.) support
this.

Could you please explain the motivation behind this? Specifically, in which
cases are iaload and aaload operations both performed on `[I` ?

If `I` and `Qjava/lang/Integer$val;` will require explicit javac
conversions, shouldn't `[I` and `[java/lang/Integer$val` also?


Regards,
--Tobi