Relates :
|
|
Relates :
|
|
Relates :
|
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.
|