hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes

Remi Forax forax at univ-mlv.fr
Thu Jul 24 17:00:38 UTC 2014


On 07/24/2014 06:35 PM, Maurizio Cimadamore wrote:
>
> On 24/07/14 17:19, Remi Forax wrote:
>>
>> On 07/24/2014 03:21 PM, Maurizio Cimadamore wrote:
>>> Hi Remi,
>>> thanks for the comments. This is an initial prototype to get things 
>>> going and unblock the work on the specializer. The current support 
>>> will be enough to compile simple classes such as Box (in Brian's 
>>> document).
>>>
>>> Said that, opcodes such as dup/pop can easily be added in the 
>>> current code by adding more 'cases' to the filtering switch.
>>>
>>> areturn is there - but it's generated in a different code path - see 
>>> Gen.visitReturn.
>>>
>>> For opcodes such as new and newarray, we need to have unerased 
>>> expression types being saved by javac somewhere, so that was a bit 
>>> beyond the scope of this patch.
>>
>> new if different of anewarray, i don't think you can specialize new.
>> anewarray is equivalent to getfield, the syntax use an internal name 
>> instead of a descriptor which is an historical glitch in my opinion
>> but if you know how to specialize getfield, you know how to 
>> specialize anewarray.
> I said new - because there will need to be something if you do
>
> new ArrayList<int>
>
> in order to point back at the unerased info. This will become 
> something else in the long run, but for now tagging 'new' will make 
> sure that the specializer will have a chance to rewrite the name of 
> the class to be instantiated.

I see, but this code is not specializable.
In my opinion, new ArrayList<int> should be rewritten to use 
invokedynamic, here is why.

I think the specializer as you call it should work at runtime, otherwise 
we will run in exactly the same trouble we have with inner classes,
binary compatibility being the biggest issue.
So there is an issue if you generate ArrayList<int> at runtime, it 
doesn't exit at compile time :)
so you can not have a name to insert in the bytecode.

For me, ArrayList<int> or ArrayList<double> should be erased as Object 
(exactly like the supertype of int[] and double[] is Object),
and the type argument should be sent as a bootstrap argument to a 
special invokedynamic.

basically
   new ArrayList<int>
can be trasformed to
   invokedynamic <init> ()Ljava/lang/Object;  [ int.class ]

likewise, any method call on ArrayList<int> should be an invokedynamic.

With that, at runtime, in the bootstrap method, you can ask the 
specializer to generate specialized class only when needed,
i.e the first time a constructor is called.


>>
>>>
>>> Regarging comparisons - the first issue is that  type-checking 
>>> support for comparisons involving 'any' type-variable is not there 
>>> yet - i.e. the compiler will reject it as of now. Once that's 
>>> allowed, you will be able to compare T with T but not T with int 
>>> (similarly as you cannot compare an ordinary type-variable with a 
>>> string). In other words, I don't believe equals() will ever be 
>>> generated - i.e. the compiler will always use if_acmpeq and the 
>>> likes, which will be tagged, eventually, in the bytecode.
>>
>> I was thinking about the opposite,
>> <any T> void m(T t1, t t2) {
>>   return t1.equals(t2);
>> }
>>
>> does this code should use if_icmpeq if T is specialized with T=int.
>
> The code above doesn't compile. It doesn't make sense (at least for 
> now) to speak about members of an 'any' type-variable, so there's no 
> equals in T.

so practically there will be at least two codes by method, the one that 
takes an Object because you can do equals on it
and the one that takes any that will use ==.

>
> Maurizio

Rémi



More information about the valhalla-dev mailing list