[9] RFR (M): 8037209: Improvements and cleanups to bytecode assembly for lambda forms

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Tue Jul 8 10:09:04 UTC 2014


I'd like to revive this review thread.

Updated version:
http://cr.openjdk.java.net/~vlivanov/8037209/webrev.04/

Paul, I'd like to address your case (if possible) separately. Right now, 
I don't see any way to avoid null check you see with your tests.

Best regards,
Vladimir Ivanov

On 3/24/14 8:33 PM, Vladimir Ivanov wrote:
> Updated version:
> http://cr.openjdk.java.net/~vlivanov/8037209/webrev.01/
>
> Changes:
>    - rebased to enum-based BasicType;
>    - decided to integrate changes for typed array getters/setters
> separately;
>
> Best regards,
> Vladimir Ivanov
>
> On 3/14/14 8:36 PM, Vladimir Ivanov wrote:
>>> Doh! crossed webrevs, thanks.
>>>
>>> Just had a quick look, this looks like a really nice improvement to
>>> the array setter/getter support, definitely simplified. IIUC the
>>> mh.viewAsType will now handle the appropriate casting. I believe it
>>> might reduce the "ceremony" for array setter/getter MHs [1].
>>>
>>> I see there is a PROFILE_LEVEL option, by default set to 0, that
>>> results in casts not being emitted:
>>>
>>> +                if (VerifyType.isNullConversion(Object.class, pclass,
>>> false)) {
>>> +                    if (PROFILE_LEVEL > 0)
>>> +                        emitReferenceCast(Object.class, arg);
>>> +                    return;
>>> +                }
>>> ...
>>> +            mv.visitLdcInsn(constantPlaceholder(cls));
>>> +            mv.visitTypeInsn(Opcodes.CHECKCAST, CLS);
>>> +            mv.visitInsn(Opcodes.SWAP);
>>> +            mv.visitMethodInsn(Opcodes.INVOKESTATIC, MHI,
>>> "castReference", CLL_SIG, false);
>>> +            if (Object[].class.isAssignableFrom(cls))
>>> +                mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY);
>>> +            else if (PROFILE_LEVEL > 0)
>>> +                mv.visitTypeInsn(Opcodes.CHECKCAST, OBJ);
>>>
>>> Can you explain a bit the rational for that?
>> These casts are redundant - they aren't required for bytecode
>> correctness. The idea behind PROFILE_LEVEL is to provide more type
>> information to JIT-compiler. Right now, type profiling occurs on every
>> checkcast instruction. So, having these additional instructions we can
>> feed C2 with more accurate information about types.
>>
>> Consider this as a hack to overcome some of the limitations of current
>> profiling implementation in VM.
>>
>> Best regards,
>> Vladimir Ivanov
>>
>>> Paul.
>>>
>>> [1] Below is an inlining trace for an array getter MH in the current
>>> code i obtained a few weeks ago when investigating CAS-based MHs for
>>> arrays:
>>>
>>> Inlining _isInstance on constant Class java/lang/Class
>>> Inlining _isInstance on constant Class [Ljava/lang/Object;
>>> Inlining _isInstance on constant Class [Ljava/lang/String;
>>> Inlining _isInstance on constant Class java/lang/String
>>>                              @ 12   unsafe.ArrayMHTest::get_mh_orig
>>> (19 bytes)   inline (hot)
>>>                                @ 12
>>> java.lang.invoke.LambdaForm$MH/924874137::invokeExact_MT (15 bytes)
>>> inline (hot)
>>>                                  @ 2
>>> java.lang.invoke.Invokers::checkExactType (30 bytes)   inline (hot)
>>>                                    @ 11
>>> java.lang.invoke.MethodHandle::type (5 bytes)   accessor
>>>                                  @ 11
>>> java.lang.invoke.LambdaForm$MH/1980556943::convert (21 bytes)   inline
>>> (hot)
>>>                                    @ 7
>>> java.lang.invoke.LambdaForm$MH/1892887290::getElement (20 bytes)
>>> inline (hot)
>>>                                      @ 16
>>> java.lang.invoke.LambdaForm$MH/816943783::convert (37 bytes)   inline
>>> (hot)
>>>                                        @ 6
>>> java.lang.invoke.LambdaForm$BMH/1350345087::reinvoke (26 bytes)
>>> inline (hot)
>>>                                          @ 12
>>> java.lang.invoke.BoundMethodHandle$Species_LL::reinvokerTarget (8
>>> bytes)   inline (hot)
>>>                                          @ 22
>>> java.lang.invoke.LambdaForm$DMH/1162873666::invokeStatic_LL_L (15
>>> bytes)   inline (hot)
>>>                                            @ 1
>>> java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes)
>>> inline (hot)
>>>                                            @ 11
>>> sun.invoke.util.ValueConversions::castReference (20 bytes)   inline
>>> (hot)
>>>                                              @ 6
>>> java.lang.Class::isInstance (0 bytes)   (intrinsic)
>>>                                        @ 17
>>> java.lang.invoke.LambdaForm$BMH/1350345087::reinvoke (26 bytes)
>>> inline (hot)
>>>                                          @ 12
>>> java.lang.invoke.BoundMethodHandle$Species_LL::reinvokerTarget (8
>>> bytes)   inline (hot)
>>>                                          @ 22
>>> java.lang.invoke.LambdaForm$DMH/1162873666::invokeStatic_LL_L (15
>>> bytes)   inline (hot)
>>>                                            @ 1
>>> java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes)
>>> inline (hot)
>>>                                            @ 11
>>> sun.invoke.util.ValueConversions::castReference (20 bytes)   inline
>>> (hot)
>>>                                              @ 6
>>> java.lang.Class::isInstance (0 bytes)   (intrinsic)
>>>                                        @ 33
>>> java.lang.invoke.MethodHandleImpl$ArrayAccessor::getElementL (10
>>> bytes)   inline (hot)
>>>                                          @ 2   java.lang.Class::cast
>>> (27 bytes)   inline (hot)
>>>                                            @ 6
>>> java.lang.Class::isInstance (0 bytes)   (intrinsic)
>>>                                    @ 17
>>> java.lang.invoke.LambdaForm$MH/91466391::convert (23 bytes)   inline
>>> (hot)
>>>                                      @ 6
>>> java.lang.invoke.LambdaForm$BMH/1350345087::reinvoke (26 bytes)
>>> inline (hot)
>>>                                        @ 12
>>> java.lang.invoke.BoundMethodHandle$Species_LL::reinvokerTarget (8
>>> bytes)   inline (hot)
>>>                                        @ 22
>>> java.lang.invoke.LambdaForm$DMH/1162873666::invokeStatic_LL_L (15
>>> bytes)   inline (hot)
>>>                                          @ 1
>>> java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes)
>>> inline (hot)
>>>                                          @ 11
>>> sun.invoke.util.ValueConversions::castReference (20 bytes)   inline
>>> (hot)
>>>                                            @ 6
>>> java.lang.Class::isInstance (0 bytes)   (intrinsic)
>>>                                      @ 19
>>> java.lang.invoke.LambdaForm$MH/349834280::identity (10 bytes)   inline
>>> (hot)
>>>                                        @ 6
>>> java.lang.invoke.LambdaForm$DMH/1357006072::invokeStatic_L_L (14
>>> bytes)   inline (hot)
>>>                                          @ 1
>>> java.lang.invoke.DirectMethodHandle::internalMemberName (8 bytes)
>>> inline (hot)
>>>                                          @ 10
>>> sun.invoke.util.ValueConversions::identity (2 bytes)   inline (hot)
>>>


More information about the mlvm-dev mailing list