On 06/17/2011 11:14 AM, Rémi Forax wrote:
> On 06/17/2011 10:58 AM, Christian Thalinger wrote:
>> On Jun 15, 2011, at 5:26 PM, Rémi Forax wrote:
>>> // with the optimization
>>> [forax@localhost binary-operation]$ time java -cp .:classes PerfOpt
>>> real    0m0.954s
>>> user    0m1.030s
>>> sys    0m0.087s
>>>
>>> // without
>>> [forax@localhost binary-operation]$ time java -cp .:classes Perf
>>> real    0m0.378s
>>> user    0m0.407s
>>> sys    0m0.081s
>>>
>>> Knowing that the double xor trick does 4 comparisons and
>>> the constant trick only two, the problem comes from either
>>> my code or the way the VM inlines the method handles.
>>>
>>> I've found no problem in my code so ... :)
>>> Playing with the VM logs, the method containing (j != MAXINT) is not inlined
>>> because it hits the maximum depth (as far as I remember this problem
>>> is new, the older algorithm, the one that didn't propagate MDO, didn't
>>> exhibit this problem).
>> I fixed a small bug in printing the inlining tree with nested MHs (we're 
>> getting flat trees in this case).  Anyway, the inlining for PerfOpt looks 
>> actually good.  Here are the inlining trees of Perf and PerfOpt:
>>
>>       888    1 %           Perf::main @ 17 (47 bytes)
>>                               @ 19   Perf::less (50 bytes)   already 
>> compiled into a big method
>>                               @ 27   java.lang.Integer::valueOf (54 bytes)   
>> inline (hot)
>>                               @ 30   
>> java.lang.invoke.MethodHandle::invokeExact (8 bytes)   inline (hot)
>>                                 @ 4   
>> java.lang.invoke.MethodHandleImpl$GuardWithTest::invoke_L2 (32 bytes)   
>> inline (hot)
>>                                   @ 6   
>> java.lang.invoke.MethodHandle::invokeExact (5 bytes)   inline (hot)
>>                                     @ 1   
>> jsr292.cookbook.binop.RT::integerCheck (16 bytes)   inline (hot)
>>                                       @ 1   java.lang.Object::getClass (0 
>> bytes)   (intrinsic)
>>                                   @ 18   
>> java.lang.invoke.MethodHandle::invokeExact (8 bytes)   inline (hot)
>>                                     @ 4   
>> java.lang.invoke.MethodHandleImpl$GuardWithTest::invoke_L2 (32 bytes)   
>> inline (hot)
>>                                       @ 6   
>> java.lang.invoke.MethodHandle::invokeExact (5 bytes)   inline (hot)
>>                                         @ 1   
>> jsr292.cookbook.binop.RT::integerCheck (16 bytes)   inline (hot)
>>                                           @ 1   java.lang.Object::getClass 
>> (0 bytes)   (intrinsic)
>>                                       @ 18   
>> java.lang.invoke.MethodHandle::invokeExact (57 bytes)   inline (hot)
>>                                         @ 31   java.lang.Integer::intValue 
>> (5 bytes)   inline (hot)
>>                                         @ 44   java.lang.Integer::intValue 
>> (5 bytes)   inline (hot)
>>                                         @ 53   
>> jsr292.cookbook.binop.RT::safeAdd (35 bytes)   inline (hot)
>>                                           @ 18   
>> java.math.BigInteger::valueOf (62 bytes)   already compiled into a medium 
>> method
>>                                           @ 23   
>> java.math.BigInteger::valueOf (62 bytes)   already compiled into a medium 
>> method
>>                                           @ 26   java.math.BigInteger::add 
>> (123 bytes)   too big
>>                                           @ 31   java.lang.Integer::valueOf 
>> (54 bytes)   inline (hot)
>>                                             @ 50   java.lang.Integer::<init> 
>>   (10 bytes)   inline (hot)
>>                                               @ 1   java.lang.Number::<init> 
>>   (5 bytes)   inline (hot)
>>                                                 @ 1   
>> java.lang.Object::<init>   (1 bytes)   inline (hot)
>>                               @ 19   Perf::less (50 bytes)   already 
>> compiled into a big method
>>
>>
>>       854    1 %           PerfOpt::main @ 17 (43 bytes)
>>                               @ 19   PerfOpt::less (50 bytes)   already 
>> compiled into a big method
>>                               @ 26   
>> java.lang.invoke.MethodHandle::invokeExact (7 bytes)   inline (hot)
>>                                 @ 3   
>> java.lang.invoke.MethodHandleImpl$GuardWithTest::invoke_L1 (29 bytes)   
>> inline (hot)
>>                                   @ 5   
>> java.lang.invoke.MethodHandle::invokeExact (5 bytes)   inline (hot)
>>                                     @ 1   
>> jsr292.cookbook.binop.RT::integerCheck (16 bytes)   inline (hot)
>>                                       @ 1   java.lang.Object::getClass (0 
>> bytes)   (intrinsic)
>>                                   @ 16   
>> java.lang.invoke.MethodHandle::invokeExact (84 bytes)   inline (hot)
>>                                     @ 11   java.lang.Integer::intValue (5 
>> bytes)   inline (hot)
>>                                     @ 20   
>> java.lang.invoke.MethodHandle::invokeExact (5 bytes)   inline (hot)
>>                                       @ 1   
>> jsr292.cookbook.binop.RT::maxIntCheck (12 bytes)   inline (hot)
>>                                     @ 27   java.lang.Integer::valueOf (54 
>> bytes)   inline (hot)
>>                                       @ 50   java.lang.Integer::<init>   (10 
>> bytes)   inline (hot)
>>                                         @ 1   java.lang.Number::<init>   (5 
>> bytes)   inline (hot)
>>                                           @ 1   java.lang.Object::<init>   
>> (1 bytes)   inline (hot)
>>                                     @ 34   java.lang.Boolean::valueOf (14 
>> bytes)   inline (hot)
>>                                     @ 43   
>> java.lang.invoke.MethodHandle::invokeExact (26 bytes)   inline (hot)
>>                                       @ 11   java.lang.Boolean::booleanValue 
>> (5 bytes)   inline (hot)
>>                                       @ 22   
>> java.lang.invoke.MethodHandleImpl::selectAlternative (10 bytes)   inline 
>> (hot)
>>                                     @ 64   java.lang.Integer::intValue (5 
>> bytes)   inline (hot)
>>                                     @ 80   
>> java.lang.invoke.MethodHandle::invokeExact (12 bytes)   inline (hot)
>>                                     @ 80   
>> java.lang.invoke.MethodHandle::invokeExact (18 bytes)   inline (hot)
>>                                       @ 4   
>> java.lang.invoke.MethodHandle::invokeExact (6 bytes)   inline (hot)
>>                                         @ 2   jsr292.cookbook.binop.RT::add 
>> (4 bytes)   inline (hot)
>>                                       @ 9   java.lang.Integer::valueOf (54 
>> bytes)   inline (hot)
>>                                         @ 50   java.lang.Integer::<init>   
>> (10 bytes)   inline (hot)
>>                                           @ 1   java.lang.Number::<init>   
>> (5 bytes)   inline (hot)
>>                                             @ 1   java.lang.Object::<init>   
>> (1 bytes)   inline (hot)
>>                                       @ 14   
>> sun.invoke.util.ValueConversions::identity (2 bytes)   inline (hot)
>>                                       @ 1   java.lang.Integer::valueOf (54 
>> bytes)   inline (hot)
>>                                         @ 50   java.lang.Integer::<init>   
>> (10 bytes)   inline (hot)
>>                                           @ 1   java.lang.Number::<init>   
>> (5 bytes)   inline (hot)
>>                                             @ 1   java.lang.Object::<init>   
>> (1 bytes)   inline (hot)
>>                                       @ 8   
>> jsr292.cookbook.binop.RT::fallbackOpLeft (115 bytes)   inline (hot)
>>                                         @ 5   java.math.BigInteger::valueOf 
>> (62 bytes)   already compiled into a medium method
>>                                         @ 10   java.lang.Object::getClass (0 
>> bytes)   (intrinsic)
>>                                         @ 33   java.lang.Integer::intValue 
>> (5 bytes)   inline (hot)
>>                                         @ 37   java.math.BigInteger::valueOf 
>> (62 bytes)   already compiled into a medium method
>>                                         @ 45   
>> java.lang.invoke.MethodHandle::invokeWithArguments (61 bytes)   too big
>>                               @ 19   PerfOpt::less (50 bytes)   already 
>> compiled into a big method
>>
>>> Moreover, the VM tries to inline some parts of the fallback method
>>> (twice :( )
>>> even if this code never called.
> It's far more readable, now :)
>
> I wonder if I haven't introduce a bug in my logic,
> there is a the boxing/unboxing of the return value of the test that
> should not occur.
> Question, does EA is also disable when MH.invokeExact is called  ?
>
>    @ 34   java.lang.Boolean::valueOf (14 bytes)   inline (hot)
>    @ 43   java.lang.invoke.MethodHandle::invokeExact (26 bytes)   inline (hot)
>      @ 11   java.lang.Boolean::booleanValue (5 bytes)   inline (hot)
>
>
> I will check my code.

Not my fault, the boxing/unboxing comes from fold(), it seems.
fold() is used to insert the result of the test of GWT into select 
alternative.

I wonder if this boxing/unboxing doesn't impact severly performance ?

>> Hmm.  I'm a little curious about how fallbackOpLeft becomes the fallback 
>> path.  Usually this is/was done with a guardWithTest.  Is selectAlternative 
>> doing this?
> isSelectAlternative is the internal method called when you create a
> guardWithTest
> with ricochet frame enabled.
>
>> I think what's happening here is, we propagate the call site count from the 
>> hIot MH call site to all its callees through the MH chain and since 
>> fallbackOpLeft is in there it gets the same call site count making it hot, 
>> while actually it isn't.
> Yes, one solution is to always set the fallback as cold.
> A better solution is to record the usage of each branch when interpreted.

Rémi

_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

Reply via email to