<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <p>Hi,</p>
    <p>After additional discussions with Vladimir I., Igor and Claes we
      tracked down the root cause to be missing profiling on
      invokestatic that is necessary for MH.linkToSpecial. (Can be seem
      in the examples earlier in this thread.) This missing profiling in
      compiled code was sometimes hidden by interpreter profiling that
      kicks in when C1 doesn't keep up with compiler requests. <br>
    </p>
    <p>This bug was be introduced and included in b120, which saw
      introduction of a lot of performance variation. In the same build
      was also indify string concat which which was assumed to be the
      cause of some of the changed behavior.</p>
    <p>The bug was intruduced by JDK-8154172 which missed that calls
      without a reciver also should have profiling. <br>
    </p>
    <p>I fixed another issue in the same code in JDK-8160543 but missed
      this case.</p>
    <p>The change is smaller than it looks at first sight. The check
      (recv != NULL) is moved out, making it only guard the nullcheck
      insertion. <br>
    </p>
    <p>Webrev: <a class="moz-txt-link-freetext"
        href="http://cr.openjdk.java.net/%7Eneliasso/8167656/webrev.02/">http://cr.openjdk.java.net/~neliasso/8167656/webrev.02/</a></p>
    <p>
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
    </p>
    <p>Testing: <br>
    </p>
    - nashorn octane for perf stability<br>
    - JCK/BINC, LinkageErrorTest for correctness<br>
    <br>
    Please have a look,<br>
    Nils
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 2016-10-26 14:20, Vladimir Ivanov
      wrote:<br>
    </div>
    <blockquote
      cite="mid:e0427b56-763b-5a08-3a2e-4f7174589215@oracle.com"
      type="cite">Nils, <br>
      <br>
      Thanks for taking care of the problem. <br>
      <br>
      It sounds like you fixed the symptoms (missed inlining
      opportunity), but not the root cause. <br>
      <br>
      Invokers are heavily shared, but it can't explain inconsistent
      profile info: the method was called 5k times, but some
      per-bytecode info is absent (counts at @11 & @14 are 0s, but
      @1 it's ~5k) [1]. The method has a single basic block and
      DMH.internalMemberName doesn't throw exceptions (it's just a field
      getter). <br>
      <br>
      It doesn't even look MH-specific. Do you know why does it happen?
      <br>
      <br>
      Best regards, <br>
      Vladimir Ivanov <br>
      <br>
      [1] <br>
      ----------------- <br>
      static
java.lang.invoke.LambdaForm$DMH/335334514::invokeSpecial_LID_V(Ljava/lang/Object;Ljava/lang/Object;ID)V<br>
        interpreter_invocation_count:     5472 <br>
        invocation_counter:               5474 <br>
        backedge_counter:                    0 <br>
        mdo size: 640 bytes <br>
      <br>
        parameter types        0: stack(0)
      'java/lang/invoke/DirectMethodHandle$Special' <br>
                               1: stack(1)
      'jdk/nashorn/internal/runtime/arrays/NumberArrayData' <br>
      0 fast_aload_0 <br>
      1 invokestatic 18
<java/lang/invoke/DirectMethodHandle.internalMemberName(Ljava/lang/Object;)Ljava/lang/Object;><br>
          bci: 1    CounterData         count(5336) <br>
                    argument types      0: stack(0)
      'java/lang/invoke/DirectMethodHandle$Special' <br>
                    return type 'java/lang/invoke/MemberName' <br>
      4 astore #5 <br>
      6 aload_1 <br>
      7 iload_2 <br>
      8 dload_3 <br>
      9 aload #5 <br>
      11 checkcast 20 <java/lang/invoke/MemberName> <br>
          bci: 11   ReceiverTypeData    count(0) nonprofiled_count(0)
      entries(0) <br>
      14 invokestatic 26
<java/lang/invoke/MethodHandle.linkToSpecial(Ljava/lang/Object;IDLjava/lang/invoke/MemberName;)V><br>
          bci: 14   CounterData         count(0) <br>
                    argument types      0: stack(0) none <br>
                                        1: stack(4) none <br>
      ----------------- <br>
      <br>
      On 10/13/16 4:02 PM, Nils Eliasson wrote: <br>
      <blockquote type="cite">Hi, <br>
        <br>
        Please review, <br>
        <br>
        Background: <br>
        The fix for JDK-8160543 "C1: Crash in java.lang.String.indexOf
        in some <br>
        java.sql tests" looked like it was causing a performance
        regression in <br>
        navierStokes benchmark. Consecutive runs of the benchmark showed
        very <br>
        high variance between results (~100% speedup). It showed a
        bimodal <br>
        behaviour where fast runs were as fast, and slow as slow, but
        the <br>
        proportion of slow increased. <br>
        <br>
        Drilling down to the cause of this was hard, any intrusive debug
        flag <br>
        (like PrintAssembly) made the benchmark end up in the fast case.
        <br>
        <br>
        Problem description: <br>
        The problem is that sometimes invokeSpecial calls aren't inlined
        because <br>
        no type profile data has been collected for that callsite even
        though it <br>
        is hot. <br>
        <br>
        This method is compiled on level 3 (full profile): <br>
        <br>
        java.lang.invoke.LambdaForm$DMH/2008276237::invokeSpecial_LID_V
        (18 bytes) <br>
            @ 1  
        java.lang.invoke.DirectMethodHandle::internalMemberName (8 <br>
        bytes)   force inline by annotation <br>
            @ 14   java.lang.invoke.MethodHandle::linkToSpecial(LIDL)V
        (0 <br>
        bytes)   MemberName not constant <br>
        <br>
        @14 is a native method: compiled as <br>
        java.lang.invoke.MethodHandle::linkToSpecial(LIDL)V (native)
        (static) <br>
        <br>
        Sometimes there are already some method data collected for <br>
        invokeSpecial_LID_V (interpreter?), then the generated code will
        look <br>
        slightly different and we will always end up in the fast case.
        If there <br>
        were no earlier profile data, it sometimes get collected and
        then we end <br>
        up in the fast case too. <br>
        <br>
        When invokeSpecial_LID_V is later compiled on level 4 (full opt)
        this <br>
        method data is available: <br>
        <br>
        ----------------- <br>
        static <br>
java.lang.invoke.LambdaForm$DMH/335334514::invokeSpecial_LID_V(Ljava/lang/Object;Ljava/lang/Object;ID)V
        <br>
        <br>
          interpreter_invocation_count:     5472 <br>
          invocation_counter:               5474 <br>
          backedge_counter:                    0 <br>
          mdo size: 640 bytes <br>
        <br>
          parameter types        0: stack(0) <br>
        'java/lang/invoke/DirectMethodHandle$Special' <br>
                                 1: stack(1) <br>
        'jdk/nashorn/internal/runtime/arrays/NumberArrayData' <br>
        0 fast_aload_0 <br>
        1 invokestatic 18 <br>
<java/lang/invoke/DirectMethodHandle.internalMemberName(Ljava/lang/Object;)Ljava/lang/Object;>
        <br>
        <br>
            bci: 1    CounterData         count(5336) <br>
                      argument types      0: stack(0) <br>
        'java/lang/invoke/DirectMethodHandle$Special' <br>
                      return type 'java/lang/invoke/MemberName' <br>
        4 astore #5 <br>
        6 aload_1 <br>
        7 iload_2 <br>
        8 dload_3 <br>
        9 aload #5 <br>
        11 checkcast 20 <java/lang/invoke/MemberName> <br>
            bci: 11   ReceiverTypeData    count(0) nonprofiled_count(0)
        entries(0) <br>
        14 invokestatic 26 <br>
<java/lang/invoke/MethodHandle.linkToSpecial(Ljava/lang/Object;IDLjava/lang/invoke/MemberName;)V>
        <br>
        <br>
            bci: 14   CounterData         count(0) <br>
                      argument types      0: stack(0) none <br>
                                          1: stack(4) none <br>
        ----------------- <br>
        <br>
        No data at bci 14 makes the inliner go: <br>
        <br>
        [.. snippet from huge inline log...] <br>
        @ 55
        java.lang.invoke.LambdaForm$DMH/221378065::invokeSpecial_LID_V
        (18 <br>
        bytes)   force inline by annotation <br>
            @ 1  
        java.lang.invoke.DirectMethodHandle::internalMemberName (8 <br>
        bytes)   force inline by annotation <br>
            @ 14
        jdk.nashorn.internal.runtime.arrays.NumberArrayData::setElem <br>
        (24 bytes)   call site not reached <br>
        .. <br>
        <br>
        @14 is a linkToSpecial that was redirected to a invokeSpecial,
        that is <br>
        linked to NumberArrayData::setElem that is missing a profile. <br>
        <br>
        We can note that the perf data is still there as the method
        parameter <br>
        profile have caught the class. <br>
        <br>
        Why does this only happens sometimes? <br>
        linkToSpecial is a shared form. It may be compiled into a
        signature <br>
        specialized method - but it is native and is missing type
        profile <br>
        counters. We will get no data when it is running. The level 3
        compiled <br>
        invokeSpecial_LID_V sometimes only live a very short time ~50ms,
        and the <br>
        callstack of the benchmark is pretty deep. The amount of
        invocations <br>
        varies between 0 and ±500, often being very low, or quite high.
        It looks <br>
        like the call is used in some phases, and depending on the
        timing it may <br>
        not have been run. <br>
        <br>
        Solution: <br>
        Don't forbid methodhandle call sites missing type profile data
        from <br>
        being inlined, the surrounding invokeSpecial probably will -
        leave it to <br>
        normal inlining heuristics to decide if it is hot enough. <br>
        <br>
        Lessons: <br>
        Type profiling of methodHandle and Lambda form code may need to
        be <br>
        revisited. We both seem to profile to little and too much.
        Native <br>
        methods get no profile, but in normal level 3 code we are
        profiling the <br>
        same reference at every use causing a lot of overhead even in
        trivial <br>
        non-branchy code. <br>
        <br>
        Testing: <br>
        The fix proposed fix makes us end up in the fast case every run.
        It <br>
        should remove a lot of variance from Nashorn benchmarks. <br>
        <br>
        Bug: <a class="moz-txt-link-freetext"
          href="https://bugs.openjdk.java.net/browse/JDK-8167656">https://bugs.openjdk.java.net/browse/JDK-8167656</a>
        <br>
        Webrev: <a class="moz-txt-link-freetext"
          href="http://cr.openjdk.java.net/%7Eneliasso/8167656/webrev.01/">http://cr.openjdk.java.net/~neliasso/8167656/webrev.01/</a>
        <br>
        <br>
        Regards, <br>
        Nils Eliasson <br>
      </blockquote>
    </blockquote>
    <br>
  </body>
</html>