Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8162384

Performance regression: bimorphic inlining may be bypassed by type speculation

XMLWordPrintable

    • b131

        Here is an example of that problem:

        private static int iterateIndirect(ByteBuffer buffer) {
        int n = buffer.remaining();
        while (n > 0 && buffer.get(n - 1) == 0) {
        n--;
        }
        return n;
        }

        Profiling is:

        static ByteBufferTest::iterateIndirect(Ljava/nio/ByteBuffer;)I
          interpreter_invocation_count: 2
          invocation_counter: 2
          backedge_counter: 156672
          mdo size: 600 bytes

        0 fast_aload_0
        1 invokevirtual 49 <java/nio/ByteBuffer.remaining()I>
          0 bci: 1 VirtualCallData count(0) nonprofiled_count(0) entries(1)
                                            'java/nio/DirectByteBuffer'(1 1.00)
                                            method_entries(0)
        4 istore_1
        5 iload_1
        6 ifle 25
          56 bci: 6 BranchData taken(0) displacement(144)
                                            not taken(96249)
        9 fast_aload_0
        10 iload_1
        11 iconst_1
        12 isub
        13 invokevirtual 50 <java/nio/ByteBuffer.get(I)B>
          88 bci: 13 VirtualCallData trap/ ByteBufferTest::iterateIndirect(class_check recompiled) count(0) nonprofiled_count(0) entries(2)
                                            'java/nio/HeapByteBuffer'(47103 0.49)
                                            'java/nio/DirectByteBuffer'(49151 0.51)
                                            method_entries(0)
        16 ifne 25
          144 bci: 16 BranchData trap(intrinsic_or_type_checked_inlining recompiled) flags(224) taken(1) displacement(56)
                                            not taken(96254)
        19 iinc #1 -1
        22 goto 5
          176 bci: 22 JumpData taken(96254) displacement(-120)
        25 iload_1
        26 ireturn

        The method is called with either a HeapByteBuffer or a DirectByteBuffer but profiling didn't run long enough to collect both at bci 1. The profiling at bci 1 DirectByteBuffer) is fed to type speculation. Call at bci 13 uses the speculation, inlines DirectByteBuffer::get(). When a HeapByteBuffer is passed to the compiled method, an uncommon trap occurs, the method is recompiled, speculation is used again to inline DirectByteBuffer::get() but because of the trap a virtual call is compiled to cover cases where the speculation fails. Given the profile data at the call, it would be much better to use bimorphic inlining and ignore speculation.

              roland Roland Westrelin
              roland Roland Westrelin
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: