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

C2 fails to hoist alignment checks

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P3 P3
    • None
    • 22
    • hotspot

      The C2 compiler should be able to hoist alignment checks out of loops but appears to be failing under certain conditions:

      ```
      Benchmark (size) Mode Cnt Score Error Units
      InternalStrLen.legacyQuadByte 1 avgt 30 1.910 ? 0.025 ns/op
      InternalStrLen.legacyQuadByte 4 avgt 30 3.768 ? 0.021 ns/op
      InternalStrLen.legacyQuadByte 16 avgt 30 11.427 ? 0.149 ns/op
      InternalStrLen.legacyQuadByte 251 avgt 30 166.094 ? 0.833 ns/op
      InternalStrLen.legacyQuadByte 1024 avgt 30 655.468 ? 5.847 ns/op
      InternalStrLen.legacyQuadByteUnaligned 1 avgt 30 1.414 ? 0.019 ns/op
      InternalStrLen.legacyQuadByteUnaligned 4 avgt 30 3.772 ? 0.069 ns/op
      InternalStrLen.legacyQuadByteUnaligned 16 avgt 30 6.786 ? 0.029 ns/op
      InternalStrLen.legacyQuadByteUnaligned 251 avgt 30 47.473 ? 0.206 ns/op
      InternalStrLen.legacyQuadByteUnaligned 1024 avgt 30 192.409 ? 0.832 ns/op
      ```

      Code:


      ```
          @Benchmark
          public int legacyQuadByte() {
              return legacy_strlen_int(quadByteSegment, 0);
          }

          @Benchmark
          public int legacyQuadByteUnaligned() {
              return unaligned_legacy_strlen_int(quadByteSegment, 0);
          }

          private static int legacy_strlen_int(MemorySegment segment, long start) {
              // iterate until overflow (String can only hold a byte[], whose length can be expressed as an int)
              for (int offset = 0; offset >= 0; offset += 4) {
                  int curr = segment.get(JAVA_INT, start + offset);
                  if (curr == 0) {
                      return offset;
                  }
              }
              throw new IllegalArgumentException("String too large");
          }

          public static int unaligned_legacy_strlen_int(MemorySegment segment, long start) {
              for (int offset = 0; offset < InternalStrLen.ArraySupport.SOFT_MAX_ARRAY_LENGTH; offset += Integer.BYTES) {
                  // We are guaranteed to be aligned here so, we can use unaligned access.
                  int curr = segment.get(JAVA_INT_UNALIGNED, start + offset);
                  if (curr == 0) {
                      return offset;
                  }
              }
              throw new IllegalArgumentException("String too large");
          }

          static class ArraySupport {
              private ArraySupport() {}

              public static final int SOFT_MAX_ARRAY_LENGTH = Integer.MAX_VALUE - 8;

          }
      ```




            Unassigned Unassigned
            pminborg Per-Ake Minborg
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: