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