specializing generic methods

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Fri Aug 29 22:46:48 UTC 2014


On 29/08/14 23:06, Paul Govereau wrote:
> Hi Maurizio,
>
> I am not sure I understand all of the details of your question, but if 
> we know that:
>
>   A<:any,z:A |- Box.make(z).t : Box<A>
>
> and (because int<:any) it is not the case that:
>
>   z:int |- Box.make(z).t : Box<int>
In this case I agree with you - one assertion implies the other; you 
can't have one w/o the other. But there are cases (see Dan example with 
numeric conversions) in which the typing assertion in the specialized 
case has a completely different form than that in the generic case.

Maurizio
>
> then, wouldn't we conclude inference wasn't working correctly?
>
> Paul
>
> On 08/29/2014 04:42 PM, Maurizio Cimadamore wrote:
>> Hi,
>> as you can see from recent commits, we are starting to tackle the
>> problem of specialized generic method calls; Brian and I were thinking
>> about the following corner-case:
>>
>>   class Box<any T> {
>>       T t;
>>
>>       static <any U> Box<U> make(U u) { return null; }
>>   }
>>
>>
>>   class Client {
>>
>>       <any Z> void testAny(Z z) {
>>           Z z2 = Box.make(z).t;
>>       }
>>
>>       <Z> void testNonAny(Z z) {
>>           Z z2 = Box.make(z).t;
>>       }
>>   }
>>
>> There are several layers of decisions to be made here:
>>
>> 1) Which of the two generic calls above should receive special treatment
>> and be rewritten as indy?
>>
>> 2) Which field access should receive special treatment and get a
>> corresponding BytecodeMapping attribute? Recall that, currently, the
>> specializer needs BytecodeMapping on member accesses in order to quickly
>> identify those members whose constant pool entries are likely to become
>> 'stale' after specialization - i.e. because the entry would need to go
>> from Box.t to Box${T=I}.t.
>>
>> 3) Consider the case where the first method is called as follows:
>>
>> testAny(1)
>>
>> How is the specializer supposed to specialize the body of the generic
>> 'testAny' method? Does this involve replaying inference where Z=int?
>>
>>
>> Our answers so far:
>>
>> 1) Only the call in testAny should be specialized using indy - the
>> second generic call is always a reference instantiation - therefore can
>> be safely skipped. In principle we could even get away with leaving the
>> first call untouched, but this will mean the specializer will have to be
>> replacing invokestatic with indy - which seems a bit too on the heavy 
>> side.
>>
>> 2) The first field access (in testAny) should get a corresponding
>> BytecodeMapping, as the field owner in the CP might need rewriting.
>>
>> 3) Our current thinking is that a simple type substitution all we need -
>> i.e. we see that the inferred return type is Box<Z> and we replace Z for
>> int, obtaining Box<int> - which is then mangled into Box${0=I}. Can you
>> think of cases where this approach would be insufficient - i.e. where
>> replaying inference would lead to a substantially different result
>> w.r.t. the one obtained through substitution?
>>
>> Questions, questions, questions...
>>
>> Maurizio
>>
>>



More information about the valhalla-dev mailing list