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

Non-constant memory segments are never treated as loop invariants

    Details

    • Type: Enhancement
    • Status: Open
    • Priority: P3
    • Resolution: Unresolved
    • Affects Version/s: 14
    • Fix Version/s: tbd
    • Component/s: hotspot

      Description

      Consider the following class:

      import jdk.incubator.foreign.MemoryAddress;
      import jdk.incubator.foreign.MemoryHandles;
      import jdk.incubator.foreign.MemoryLayout;
      import jdk.incubator.foreign.MemoryLayouts;
      import jdk.incubator.foreign.MemorySegment;
      import jdk.incubator.foreign.SequenceLayout;

      import java.lang.invoke.MethodHandle;
      import java.lang.invoke.VarHandle;
      import java.nio.ByteOrder;

      public class PanamaPoint implements AutoCloseable {
          private static final SequenceLayout LAYOUT = MemoryLayout.ofSequence(MemoryLayout.ofStruct(
                  MemoryLayouts.JAVA_INT.withOrder(ByteOrder.nativeOrder()).withName("x"),
                  MemoryLayouts.JAVA_INT.withOrder(ByteOrder.nativeOrder()).withName("y")));
          private static final VarHandle VH_x = LAYOUT.varHandle(int.class, MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("x"));
          private static final VarHandle VH_y = LAYOUT.varHandle(int.class, MemoryLayout.PathElement.sequenceElement(), MemoryLayout.PathElement.groupElement("y"));

          private final MemorySegment segment;
          private final MemoryAddress base;
          public PanamaPoint(int size) {
              this.segment = MemorySegment.allocateNative(LAYOUT.elementLayout().byteSize() * size);
              this.base = segment.baseAddress();
          }
          public void setX(int x, int pos) {
              VH_x.set(base, (long)pos, x);
          }
          public int getX(int pos) {
              return (int) VH_x.get(base, (long)pos);
          }
          public void setY(int y, int pos) {
              VH_y.set(base, (long)pos, y);
          }
          public int getY(int pos) {
              return (int) VH_y.get(base, (long)pos);
          }
          @Override
          public void close() {
              segment.close();
          }
      }

      And the following benchmark:

      @Benchmark
          public int panama_get() throws Throwable {
              int res = 0;
              for (int i = 0 ; i < SIZE ; i++) {
                  res+= panamaPoint.getX(i);
              }
              return res;
          }

      Despite the segment being accessed stays the same across the entire loop, a quick look at the generated code reveals that no hoisting is taking place - that is, upon every access we pay full cost for ownership checks, liveness check, bounds check, alignment check, read only check.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                mcimadamore Maurizio Cimadamore
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated: