Indirect specialized calls

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Tue Sep 23 13:44:54 UTC 2014


In itself, the bytecode looks good. This seems caused by the fact that 
the specializer is not specializing the static arguments in the 
bootstrap method. If you run the example with this useful option (thx 
Brian!):

-Dvalhalla.dumpProxyClasses=path_to_specialized_classes

The specializer will dump all classes on a given folder. I did that and 
javap'ed the specialized class  SpecializationTest$Nested${0=I} and 
found the following code for 'call':

public int call(SpecializationTest${0=I});
     descriptor: (LSpecializationTest${0=I};)I
     flags: ACC_PUBLIC
     Code:
       stack=1, locals=2, args_size=2
          0: aload_1
          1: invokedynamic #46,  0             // InvokeDynamic 
#0:get:(LSpecializationTest;)Ljava/lang/Object;
          6: ireturn
     Signature: #29                          // 
(LSpecializationTest${0=I};)I
}
BootstrapMethods:
   0: #38 invokestatic 
java/lang/invoke/GenericMethodSpecializer.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
     Method arguments:
       #43 invokestatic 
SpecializationTest.get:(LSpecializationTest;)Ljava/lang/Object;
       #45 TTT;

As yo can see, the BSM attribute in the specialized class has a bad 
method handle - it says get(LSpecializationTest) where it should 
probably say get(LSpecializationTest{0=I}) - hence the error. We are 
working towards hunting those bugs down.

Thanks
Maurizio

On 23/09/14 14:09, Jan Lahoda wrote:
> Hello,
>
> While experimenting with accessors to private specialized fields, I 
> ran across a case where javac produces a classfile that crashes at 
> runtime (on a custom build from valhalla forest). I apologize if this 
> is a known problem, or if I am doing something wrong.
>
> The code is like this:
> ---
> public class SpecializationTest<any T> {
>
>     public T i;
>
>     public static <any TT> TT get(SpecializationTest<TT> t) {
>         return t.i;
>     }
>
>     public static void main(String[] args) {
>         Nested.main(args);
>     }
>
>     public static class Nested<any TT> {
>         public static void main(String[] args) {
>             SpecializationTest<int> v = new SpecializationTest<>();
>
>             new Nested<int>().call(v);
>         }
>         public TT call(SpecializationTest<TT> v) {
>             return get(v);
>         }
>     }
> }
> ---
>
> The output of javap for the compiled classes is attached.
>
> Running the compiled class leads to:
> ---
> Specializing SpecializationTest${0=I}; searching for 
> SpecializationTest.class (not found)
> Specializing SpecializationTest${0=I}; searching for 
> SpecializationTest.class (found)
> Specializing SpecializationTest$Nested${0=I}; searching for 
> SpecializationTest$Nested.class (not found)
> Specializing SpecializationTest$Nested${0=I}; searching for 
> SpecializationTest$Nested.class (found)
> Specializing (LSpecializationTest;)Ljava/lang/Object; to 
> (LSpecializationTest${0=I};)I
> Exception in thread "main" java.lang.VerifyError: Bad type on operand 
> stack
> Exception Details:
>   Location:
> SpecializationTest$Nested${0=I}.call(LSpecializationTest${0=I};)I @1: 
> invokedynamic
>   Reason:
>     Type 'SpecializationTest${0=I}' (current frame, stack[0]) is not 
> assignable to 'SpecializationTest'
>   Current Frame:
>     bci: @1
>     flags: { }
>     locals: { 'SpecializationTest$Nested${0=I}', 
> 'SpecializationTest${0=I}' }
>     stack: { 'SpecializationTest${0=I}' }
>   Bytecode:
>     0000000: 2bba 002e 0000 ac
>
>         at SpecializationTest$Nested.main(SpecializationTest.java:17)
>         at SpecializationTest.main(SpecializationTest.java:10)
> ---
>
> Any idea what is wrong?
>
> Thanks,
>     Jan




More information about the valhalla-dev mailing list