specializing generic methods

Paul Govereau paul.govereau at oracle.com
Fri Aug 29 22:06:49 UTC 2014


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>

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