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

Suboptimal code generation around Preconditions.checkIndex intrinsic with AVX2

XMLWordPrintable

    • b14
    • x86

        JDK-8268698 changed from a custom checkIndex to use Preconditions.checkIndex in a number of places, which cause a small regression in a few microbenchmarks.

        Cursory examination of assembly shows that likely unnecessary vzeroupper instructions are emitted in a few places.

        -prof perfasm of StringBuilders::charAtLatin1 on a Intel SandyBridge system (AVX=2 default):

        c2, level 4, org.openjdk.bench.java.lang.StringBuilders::charAtLatin1, version 648 (91 bytes)

                    # {method} {0x00007f35abc73c50} 'charAtLatin1' '()C' in 'org/openjdk/bench/java/lang/StringBuilders'
                    # [sp+0x30] (sp of caller)
                    0x00007f35dd247e20: mov 0x8(%rsi),%r10d
                    0x00007f35dd247e24: movabs $0x800000000,%r11
                    0x00007f35dd247e2e: add %r11,%r10
                    0x00007f35dd247e31: cmp %r10,%rax
                    0x00007f35dd247e34: jne 0x00007f35d56c3780 ; {runtime_call ic_miss_stub}
                    0x00007f35dd247e3a: xchg %ax,%ax
                    0x00007f35dd247e3c: nopl 0x0(%rax)
                  [Verified Entry Point]
          1.62% 0x00007f35dd247e40: mov %eax,-0x14000(%rsp)
         10.14% 0x00007f35dd247e47: push %rbp
          5.21% 0x00007f35dd247e48: sub $0x20,%rsp ;*synchronization entry
                                                                              ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@-1 (line 345)
                    0x00007f35dd247e4c: mov 0xc(%rsi),%r9d ;*getfield charAt_index {reexecute=0 rethrow=0 return_oop=0}
                                                                              ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@5 (line 345)
         25.33% 0x00007f35dd247e50: mov 0x24(%rsi),%r11d ;*getfield sbLatin1 {reexecute=0 rethrow=0 return_oop=0}
                                                                              ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@1 (line 345)
                    0x00007f35dd247e54: mov 0xc(%r12,%r11,8),%r10d ; implicit exception: dispatches to 0x00007f35dd247f00
                                                                              ;*getfield count {reexecute=0 rethrow=0 return_oop=0}
                                                                              ; - java.lang.AbstractStringBuilder::charAt@2 (line 352)
                                                                              ; - java.lang.StringBuilder::charAt@2 (line 87)
                                                                              ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@8 (line 345)
                    0x00007f35dd247e59: test %r10d,%r10d
                    0x00007f35dd247e5c: jl 0x00007f35dd247ecc
                    0x00007f35dd247e5e: cmp %r10d,%r9d
                 ╭ 0x00007f35dd247e61: jae 0x00007f35dd247e9c
          2.89% │ 0x00007f35dd247e63: movsbl 0x10(%r12,%r11,8),%ebp ;*invokestatic checkIndex {reexecute=0 rethrow=0 return_oop=0}
                 │ ; - java.lang.AbstractStringBuilder::charAt@8 (line 352)
                 │ ; - java.lang.StringBuilder::charAt@2 (line 87)
                 │ ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@8 (line 345)
                 │ 0x00007f35dd247e69: test %ebp,%ebp
                 │ 0x00007f35dd247e6b: jne 0x00007f35dd247ee8 ;*ifne {reexecute=0 rethrow=0 return_oop=0}
                 │ ; - java.lang.AbstractStringBuilder::isLatin1@10 (line 1676)
                 │ ; - java.lang.AbstractStringBuilder::charAt@13 (line 353)
                 │ ; - java.lang.StringBuilder::charAt@2 (line 87)
                 │ ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@8 (line 345)
                 │ 0x00007f35dd247e6d: mov 0x14(%r12,%r11,8),%ebp ;*getfield value {reexecute=0 rethrow=0 return_oop=0}
                 │ ; - java.lang.AbstractStringBuilder::charAt@20 (line 354)
                 │ ; - java.lang.StringBuilder::charAt@2 (line 87)
                 │ ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@8 (line 345)
                 │ 0x00007f35dd247e72: mov 0xc(%r12,%rbp,8),%r10d ; implicit exception: dispatches to 0x00007f35dd247f10
          1.62% │ 0x00007f35dd247e77: cmp %r10d,%r9d
                 │ 0x00007f35dd247e7a: jae 0x00007f35dd247eb8
                 │ 0x00007f35dd247e7c: lea (%r12,%rbp,8),%r10
                 │ 0x00007f35dd247e80: movzbl 0x10(%r10,%r9,1),%eax ;*iand {reexecute=0 rethrow=0 return_oop=0}
                 │ ; - java.lang.AbstractStringBuilder::charAt@28 (line 354)
                 │ ; - java.lang.StringBuilder::charAt@2 (line 87)
                 │ ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@8 (line 345)
          3.31% │ 0x00007f35dd247e86: vzeroupper
          1.55% │ 0x00007f35dd247e89: add $0x20,%rsp
                 │ 0x00007f35dd247e8d: pop %rbp
                 │ 0x00007f35dd247e8e: cmp 0x338(%r15),%rsp ; {poll_return}
                 │ 0x00007f35dd247e95: ja 0x00007f35dd247f20
          1.55% │ 0x00007f35dd247e9b: retq
                 ↘ 0x00007f35dd247e9c: mov $0xffffffe4,%esi
                    0x00007f35dd247ea1: mov %r11d,%ebp
                    0x00007f35dd247ea4: mov %r9d,0x4(%rsp)
                    0x00007f35dd247ea9: mov %r10d,0x8(%rsp)
                    0x00007f35dd247eae: xchg %ax,%ax
                    0x00007f35dd247eb0: vzeroupper
                    0x00007f35dd247eb3: callq 0x00007f35d56c9000 ; ImmutableOopMap {rbp=NarrowOop }
                                                                              ;*invokestatic checkIndex {reexecute=0 rethrow=0 return_oop=0}
                                                                              ; - java.lang.AbstractStringBuilder::charAt@8 (line 352)
                                                                              ; - java.lang.StringBuilder::charAt@2 (line 87)

        UseAVX=0|1 improves microbenchmark score by 1.2ns/op (~1.06x):


        UseAVX=1

        c2, level 4, org.openjdk.bench.java.lang.StringBuilders::charAtLatin1, version 647 (88 bytes)

                    # {method} {0x00007f5687873c50} 'charAtLatin1' '()C' in 'org/openjdk/bench/java/lang/StringBuilders'
                    # [sp+0x30] (sp of caller)
                    0x00007f56b92471a0: mov 0x8(%rsi),%r10d
                    0x00007f56b92471a4: movabs $0x800000000,%r11
                    0x00007f56b92471ae: add %r11,%r10
                    0x00007f56b92471b1: cmp %r10,%rax
                    0x00007f56b92471b4: jne 0x00007f56b16c3780 ; {runtime_call ic_miss_stub}
                    0x00007f56b92471ba: xchg %ax,%ax
                    0x00007f56b92471bc: nopl 0x0(%rax)
                  [Verified Entry Point]
          1.71% 0x00007f56b92471c0: mov %eax,-0x14000(%rsp)
         11.09% 0x00007f56b92471c7: push %rbp
          7.29% 0x00007f56b92471c8: sub $0x20,%rsp ;*synchronization entry
                                                                              ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@-1 (line 345)
                    0x00007f56b92471cc: mov 0xc(%rsi),%r9d ;*getfield charAt_index {reexecute=0 rethrow=0 return_oop=0}
                                                                              ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@5 (line 345)
         28.14% 0x00007f56b92471d0: mov 0x24(%rsi),%r11d ;*getfield sbLatin1 {reexecute=0 rethrow=0 return_oop=0}
                                                                              ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@1 (line 345)
                    0x00007f56b92471d4: mov 0xc(%r12,%r11,8),%r10d ; implicit exception: dispatches to 0x00007f56b924726c
                                                                              ;*getfield count {reexecute=0 rethrow=0 return_oop=0}
                                                                              ; - java.lang.AbstractStringBuilder::charAt@2 (line 352)
                                                                              ; - java.lang.StringBuilder::charAt@2 (line 87)
                                                                              ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@8 (line 345)
                    0x00007f56b92471d9: test %r10d,%r10d
                    0x00007f56b92471dc: jl 0x00007f56b9247240
                    0x00007f56b92471de: cmp %r10d,%r9d
                 ╭ 0x00007f56b92471e1: jae 0x00007f56b9247219
          3.21% │ 0x00007f56b92471e3: movsbl 0x10(%r12,%r11,8),%ebp ;*invokestatic checkIndex {reexecute=0 rethrow=0 return_oop=0}
                 │ ; - java.lang.AbstractStringBuilder::charAt@8 (line 352)
                 │ ; - java.lang.StringBuilder::charAt@2 (line 87)
                 │ ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@8 (line 345)
                 │ 0x00007f56b92471e9: test %ebp,%ebp
                 │ 0x00007f56b92471eb: jne 0x00007f56b9247258 ;*ifne {reexecute=0 rethrow=0 return_oop=0}
                 │ ; - java.lang.AbstractStringBuilder::isLatin1@10 (line 1676)
                 │ ; - java.lang.AbstractStringBuilder::charAt@13 (line 353)
                 │ ; - java.lang.StringBuilder::charAt@2 (line 87)
                 │ ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@8 (line 345)
                 │ 0x00007f56b92471ed: mov 0x14(%r12,%r11,8),%ebp ;*getfield value {reexecute=0 rethrow=0 return_oop=0}
                 │ ; - java.lang.AbstractStringBuilder::charAt@20 (line 354)
                 │ ; - java.lang.StringBuilder::charAt@2 (line 87)
                 │ ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@8 (line 345)
                 │ 0x00007f56b92471f2: mov 0xc(%r12,%rbp,8),%r10d ; implicit exception: dispatches to 0x00007f56b924727c
          1.64% │ 0x00007f56b92471f7: cmp %r10d,%r9d
                 │ 0x00007f56b92471fa: jae 0x00007f56b9247230
                 │ 0x00007f56b92471fc: lea (%r12,%rbp,8),%r10
                 │ 0x00007f56b9247200: movzbl 0x10(%r10,%r9,1),%eax ;*iand {reexecute=0 rethrow=0 return_oop=0}
                 │ ; - java.lang.AbstractStringBuilder::charAt@28 (line 354)
                 │ ; - java.lang.StringBuilder::charAt@2 (line 87)
                 │ ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@8 (line 345)
          3.45% │ 0x00007f56b9247206: add $0x20,%rsp
                 │ 0x00007f56b924720a: pop %rbp
                 │ 0x00007f56b924720b: cmp 0x338(%r15),%rsp ; {poll_return}
                 │ 0x00007f56b9247212: ja 0x00007f56b924728c
          1.74% │ 0x00007f56b9247218: retq
                 ↘ 0x00007f56b9247219: mov $0xffffffe4,%esi
                    0x00007f56b924721e: mov %r11d,%ebp
                    0x00007f56b9247221: mov %r9d,0x4(%rsp)
                    0x00007f56b9247226: mov %r10d,0x8(%rsp)
                    0x00007f56b924722b: callq 0x00007f56b16c9000 ; ImmutableOopMap {rbp=NarrowOop }
                                                                              ;*invokestatic checkIndex {reexecute=0 rethrow=0 return_oop=0}
                                                                              ; - java.lang.AbstractStringBuilder::charAt@8 (line 352)
                                                                              ; - java.lang.StringBuilder::charAt@2 (line 87)
                                                                              ; - org.openjdk.bench.java.lang.StringBuilders::charAtLatin1@8 (line 345)
                                                                              ; {runtime_call UncommonTrapBlob}

        Disabling the Preconditions_checkIndex intrinsic improves benchmark score similarly, but with slightly different code shape:

        c2, level 4, org.openjdk.bench.java.lang.StringBuilders::charAtUtf16, version 658 (77 bytes)

                    # {method} {0x00007fe485c73d18} 'charAtUtf16' '()C' in 'org/openjdk/bench/java/lang/StringBuilders'
                    # [sp+0x40] (sp of caller)
                    0x00007fe4b124a020: mov 0x8(%rsi),%r10d
                    0x00007fe4b124a024: movabs $0x800000000,%r11
                    0x00007fe4b124a02e: add %r11,%r10
                    0x00007fe4b124a031: cmp %r10,%rax
                    0x00007fe4b124a034: jne 0x00007fe4a96c3780 ; {runtime_call ic_miss_stub}
                    0x00007fe4b124a03a: xchg %ax,%ax
                    0x00007fe4b124a03c: nopl 0x0(%rax)
                  [Verified Entry Point]
          2.74% 0x00007fe4b124a040: mov %eax,-0x14000(%rsp)
          9.91% 0x00007fe4b124a047: push %rbp
          6.59% 0x00007fe4b124a048: sub $0x30,%rsp ;*synchronization entry
                                                                              ; - org.openjdk.bench.java.lang.StringBuilders::charAtUtf16@-1 (line 351)
                    0x00007fe4b124a04c: mov 0xc(%rsi),%ecx ;*getfield charAt_index {reexecute=0 rethrow=0 return_oop=0}
                                                                              ; - org.openjdk.bench.java.lang.StringBuilders::charAtUtf16@5 (line 351)
         12.96% 0x00007fe4b124a04f: mov 0x28(%rsi),%r11d ;*getfield sbUtf16 {reexecute=0 rethrow=0 return_oop=0}
                                                                              ; - org.openjdk.bench.java.lang.StringBuilders::charAtUtf16@1 (line 351)
                    0x00007fe4b124a053: mov 0xc(%r12,%r11,8),%r10d ; implicit exception: dispatches to 0x00007fe4b124a0e4
                                                                              ;*getfield count {reexecute=0 rethrow=0 return_oop=0}
                                                                              ; - java.lang.AbstractStringBuilder::charAt@2 (line 352)
                                                                              ; - java.lang.StringBuilder::charAt@2 (line 87)
                                                                              ; - org.openjdk.bench.java.lang.StringBuilders::charAtUtf16@8 (line 351)
                    0x00007fe4b124a058: test %ecx,%ecx
                 ╭ 0x00007fe4b124a05a: jl 0x00007fe4b124a08e ;*iflt {reexecute=0 rethrow=0 return_oop=0}
                 │ ; - jdk.internal.util.Preconditions::checkIndex@1 (line 301)
                 │ ; - java.lang.AbstractStringBuilder::charAt@8 (line 352)
                 │ ; - java.lang.StringBuilder::charAt@2 (line 87)
                 │ ; - org.openjdk.bench.java.lang.StringBuilders::charAtUtf16@8 (line 351)
          1.42% │ 0x00007fe4b124a05c: cmp %r10d,%ecx
                 │ 0x00007fe4b124a05f: jge 0x00007fe4b124a0a8 ;*if_icmplt {reexecute=0 rethrow=0 return_oop=0}
                 │ ; - jdk.internal.util.Preconditions::checkIndex@6 (line 301)
                 │ ; - java.lang.AbstractStringBuilder::charAt@8 (line 352)
                 │ ; - java.lang.StringBuilder::charAt@2 (line 87)
                 │ ; - org.openjdk.bench.java.lang.StringBuilders::charAtUtf16@8 (line 351)
          1.80% │ 0x00007fe4b124a061: movsbl 0x10(%r12,%r11,8),%r8d ;*getfield coder {reexecute=0 rethrow=0 return_oop=0}
                 │ ; - java.lang.AbstractStringBuilder::isLatin1@7 (line 1676)
                 │ ; - java.lang.AbstractStringBuilder::charAt@13 (line 353)
                 │ ; - java.lang.StringBuilder::charAt@2 (line 87)
                 │ ; - org.openjdk.bench.java.lang.StringBuilders::charAtUtf16@8 (line 351)
                 │ 0x00007fe4b124a067: test %r8d,%r8d
                 │ 0x00007fe4b124a06a: je 0x00007fe4b124a0c4 ;*ifeq {reexecute=0 rethrow=0 return_oop=0}
                 │ ; - java.lang.AbstractStringBuilder::charAt@16 (line 353)
                 │ ; - java.lang.StringBuilder::charAt@2 (line 87)
                 │ ; - org.openjdk.bench.java.lang.StringBuilders::charAtUtf16@8 (line 351)
                 │ 0x00007fe4b124a06c: mov 0x14(%r12,%r11,8),%r11d ;*getfield value {reexecute=0 rethrow=0 return_oop=0}
                 │ ; - java.lang.AbstractStringBuilder::charAt@32 (line 356)
                 │ ; - java.lang.StringBuilder::charAt@2 (line 87)
                 │ ; - org.openjdk.bench.java.lang.StringBuilders::charAtUtf16@8 (line 351)
                 │ 0x00007fe4b124a071: lea (%r12,%r11,8),%r10
          1.77% │ 0x00007fe4b124a075: movzwl 0x10(%r10,%rcx,2),%eax ;*invokestatic getChar {reexecute=0 rethrow=0 return_oop=0}
                 │ ; - java.lang.AbstractStringBuilder::charAt@36 (line 356)
                 │ ; - java.lang.StringBuilder::charAt@2 (line 87)
                 │ ; - org.openjdk.bench.java.lang.StringBuilders::charAtUtf16@8 (line 351)
          5.96% │ 0x00007fe4b124a07b: add $0x30,%rsp
                 │ 0x00007fe4b124a07f: pop %rbp
                 │ 0x00007fe4b124a080: cmp 0x338(%r15),%rsp ; {poll_return}
                 │ 0x00007fe4b124a087: ja 0x00007fe4b124a0f0
          1.56% │ 0x00007fe4b124a08d: retq
                 ↘ 0x00007fe4b124a08e: mov $0xffffff45,%esi
                    0x00007fe4b124a093: mov %r11d,%ebp
                    0x00007fe4b124a096: mov %ecx,0x4(%rsp)
                    0x00007fe4b124a09a: mov %r10d,0x8(%rsp)
                    0x00007fe4b124a09f: mov %ecx,0xc(%rsp)
                    0x00007fe4b124a0a3: callq 0x00007fe4a96c9000 ; ImmutableOopMap {rbp=NarrowOop }
                                                                              ;*iflt {reexecute=1 rethrow=0 return_oop=0}
                                                                              ; - (reexecute) jdk.internal.util.Preconditions::checkIndex@1 (line 301)
                                                                              ; - java.lang.AbstractStringBuilder::charAt@8 (line 352)
                                                                              ; - java.lang.StringBuilder::charAt@2 (line 87)

              yyang Yi Yang
              redestad Claes Redestad
              Votes:
              0 Vote for this issue
              Watchers:
              9 Start watching this issue

                Created:
                Updated:
                Resolved: