MethodHandle.bindTo chain fails with "IllegalArgumentException: no leading reference parameter"

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Wed Jul 26 12:11:37 UTC 2017


Sure, it's definitely out of scope for MVT.

> I first thought of it as a javac bug, but now I'm less sure. I mean, 
> yes, it's buggy, but the root of the problem here is that javac doesn't 
> know how to 'box a value'. Note that this is a true 'Valhalla value', 
> not an MVT one, so there's no POJO to fall back to. We could have javac 
> generate some 'vbox' before storing the value in the array, but that 
> would not achieve much, I think - as vbox/vubox specifically rely on the 
> duality between value-capable-class and derived-value-class that's 
> builtin in MVT. W/o MVT there's no such duality and, as a consequence, 
> no easy way to 'box' a value.

I had an impression that Q-type & L-type duality is part of long-term 
vision for value types and vbox/vunbox bytecodes will stay.

But it doesn't necessarily pass reality check :-)

Best regards,
Vladimir Ivanov

> Some approaches that have been discussed in the past were either let the 
> VM to synthesize a box for a value, or (preferred approach) have javac 
> to generate it - while I don't object for such experimental work to be 
> carried out somewhere, I'm not sure that this work truly belongs to the 
> MVT branch - where value class declaration with __ByValue is there more 
> in order to aid test development.
> 
> So I'd reluctantly suggest that this is a test bug. The test is 
> uncovering a well known issue with general support for value types in 
> the language (how to do boxing?) but that has little to do with MVT itself.
> 
> Maurizio
> 
> 
> On 25/07/17 19:00, Vladimir Ivanov wrote:
>>> If you are using value types straight from source code (e.g. 
>>> __Value), then yes, this appears to be a problem in javac. However, 
>>> if you are just using value-capable classes, then javac shouldn't 
>>> have much say in what you are trying to do, so, if that's the case it 
>>> would point more in the MH direction.
>>
>> It's the former case. The exception is thrown from javac-generated code.
>>
>>   MethodHandle mh2 = MethodHandles.insertArguments(mh1, 0, test_vt);
>>
>> is translated into:
>>
>> 11: anewarray     #7                  // class java/lang/Object
>> ...
>> 17: getfield      #3                  // Field test_vt:QMyValue1;
>> 20: aastore
>> 21: invokestatic  #8                  // Method 
>> java/lang/invoke/MethodHandles.insertArguments:(Ljava/lang/invoke/MethodHandle;I[Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle; 
>>
>>
>> where test_vt is a Q-typed field:
>>
>>   MyValue1 test_vt = MyValue1.createDefaultInline();
>>
>> __ByValue final class MyValue1 {
>> ...
>>   __ValueFactory static MyValue1 createDefaultInline() {
>>     return __MakeDefault MyValue1();
>>   }
>> }
>>
>> aastore @ 20 tries to write a Q-typed value (loaded from test_vt) into 
>> Object[] before passing it into MethodHandles.insertArguments() which 
>> is vararg method.
>>
>> I'd expect test_vt to be boxed first.
>>
>> Best regards,
>> Vladimir Ivanov
>>
>>
>>>
>>> Maurizio
>>>
>>>
>>> On 25/07/17 18:21, Vladimir Ivanov wrote:
>>>>> Changing
>>>>>      MethodHandle mh2 = mh1.bindTo(test_vt);
>>>>> to
>>>>>      MethodHandle mh2 = MethodHandles.insertArguments(mh1, 0, 
>>>>> test_vt);
>>>>> fails with:
>>>>>
>>>>> Exception in thread "main" java.lang.ArrayStoreException: MyValue1
>>>>>     at Test.test(Test.java:35)
>>>>>     at Test.main(Test.java:41)
>>>>>
>>>>> Why's that?
>>>>
>>>> I'd say it's a problem in javac with auto-boxing of Q-types when 
>>>> calling vararg methods.
>>>>
>>>> It tries to store a Q-typed value into an Object[] which generates 
>>>> an ArrayStoreException:
>>>>
>>>>   long test() throws java.lang.Throwable;
>>>> ...
>>>>         10: iconst_1
>>>>         11: anewarray     #7                  // class java/lang/Object
>>>>         14: dup
>>>>         15: iconst_0
>>>>         16: aload_0
>>>>         17: getfield      #3                  // Field 
>>>> test_vt:QMyValue1;
>>>>         20: aastore
>>>>         21: invokestatic  #8                  // Method 
>>>> java/lang/invoke/MethodHandles.insertArguments:(Ljava/lang/invoke/MethodHandle;I[Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle; 
>>>>
>>>>
>>>> Best regards,
>>>> Vladimir Ivanov
>>>
> 


More information about the valhalla-dev mailing list