RFR(S): 8162384: Performance regression: bimorphic inlining may be bypassed by type speculation

Roland Westrelin rwestrel at redhat.com
Fri Jul 22 09:37:42 UTC 2016


http://cr.openjdk.java.net/~roland/8162384/webrev.00/

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 eventually, 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.


More information about the hotspot-compiler-dev mailing list