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

Non-constant memory segments are never treated as loop invariants

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Unresolved
    • Icon: P3 P3
    • tbd
    • 14
    • hotspot

      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.

            Unassigned Unassigned
            mcimadamore Maurizio Cimadamore
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: