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