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.
> 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.
> -- Christian
Rémi
_______________________________________________
mlvm-dev mailing list
[email protected]
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev