diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java index 59b43d0b7d5..0191306881b 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleStatics.java @@ -62,6 +62,7 @@ class MethodHandleStatics { static final boolean VAR_HANDLE_GUARDS; static final int MAX_ARITY; static final boolean VAR_HANDLE_IDENTITY_ADAPT; + static final boolean VAR_HANDLE_SEGMENT_FORCE_EXACT; static final ClassFileDumper DUMP_CLASS_FILES; static { @@ -91,6 +92,8 @@ class MethodHandleStatics { props.getProperty("java.lang.invoke.VarHandle.VAR_HANDLE_GUARDS", "true")); VAR_HANDLE_IDENTITY_ADAPT = Boolean.parseBoolean( props.getProperty("java.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT", "false")); + VAR_HANDLE_SEGMENT_FORCE_EXACT = Boolean.parseBoolean( + props.getProperty("java.lang.invoke.VarHandle.VAR_HANDLE_SEGMENT_FORCE_EXACT", "false")); // Do not adjust this except for special platforms: MAX_ARITY = Integer.parseInt( diff --git a/src/java.base/share/classes/java/lang/invoke/VarHandles.java b/src/java.base/share/classes/java/lang/invoke/VarHandles.java index c0db5ddb866..0a393200447 100644 --- a/src/java.base/share/classes/java/lang/invoke/VarHandles.java +++ b/src/java.base/share/classes/java/lang/invoke/VarHandles.java @@ -41,6 +41,7 @@ import java.util.concurrent.ConcurrentMap; import java.util.stream.Stream; import static java.lang.invoke.MethodHandleStatics.UNSAFE; +import static java.lang.invoke.MethodHandleStatics.VAR_HANDLE_SEGMENT_FORCE_EXACT; import static java.lang.invoke.MethodHandleStatics.VAR_HANDLE_IDENTITY_ADAPT; import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException; @@ -317,7 +318,7 @@ final class VarHandles { } long size = Utils.byteWidthOfPrimitive(carrier); boolean be = byteOrder == ByteOrder.BIG_ENDIAN; - boolean exact = false; + boolean exact = VAR_HANDLE_SEGMENT_FORCE_EXACT; if (carrier == byte.class) { return maybeAdapt(new VarHandleSegmentAsBytes(be, size, alignmentMask, exact)); diff --git a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java index 361a10cf49b..de0ad6603d5 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java @@ -736,235 +736,235 @@ public abstract sealed class AbstractMemorySegmentImpl @ForceInline @Override public byte get(ValueLayout.OfByte layout, long offset) { - return (byte) layout.varHandle().get(this, offset); + return (byte) layout.varHandle().get((MemorySegment)this, offset); } @ForceInline @Override public void set(ValueLayout.OfByte layout, long offset, byte value) { - layout.varHandle().set(this, offset, value); + layout.varHandle().set((MemorySegment)this, offset, value); } @ForceInline @Override public boolean get(ValueLayout.OfBoolean layout, long offset) { - return (boolean) layout.varHandle().get(this, offset); + return (boolean) layout.varHandle().get((MemorySegment)this, offset); } @ForceInline @Override public void set(ValueLayout.OfBoolean layout, long offset, boolean value) { - layout.varHandle().set(this, offset, value); + layout.varHandle().set((MemorySegment)this, offset, value); } @ForceInline @Override public char get(ValueLayout.OfChar layout, long offset) { - return (char) layout.varHandle().get(this, offset); + return (char) layout.varHandle().get((MemorySegment)this, offset); } @ForceInline @Override public void set(ValueLayout.OfChar layout, long offset, char value) { - layout.varHandle().set(this, offset, value); + layout.varHandle().set((MemorySegment)this, offset, value); } @ForceInline @Override public short get(ValueLayout.OfShort layout, long offset) { - return (short) layout.varHandle().get(this, offset); + return (short) layout.varHandle().get((MemorySegment)this, offset); } @ForceInline @Override public void set(ValueLayout.OfShort layout, long offset, short value) { - layout.varHandle().set(this, offset, value); + layout.varHandle().set((MemorySegment)this, offset, value); } @ForceInline @Override public int get(ValueLayout.OfInt layout, long offset) { - return (int) layout.varHandle().get(this, offset); + return (int) layout.varHandle().get((MemorySegment)this, offset); } @ForceInline @Override public void set(ValueLayout.OfInt layout, long offset, int value) { - layout.varHandle().set(this, offset, value); + layout.varHandle().set((MemorySegment)this, offset, value); } @ForceInline @Override public float get(ValueLayout.OfFloat layout, long offset) { - return (float) layout.varHandle().get(this, offset); + return (float) layout.varHandle().get((MemorySegment)this, offset); } @ForceInline @Override public void set(ValueLayout.OfFloat layout, long offset, float value) { - layout.varHandle().set(this, offset, value); + layout.varHandle().set((MemorySegment)this, offset, value); } @ForceInline @Override public long get(ValueLayout.OfLong layout, long offset) { - return (long) layout.varHandle().get(this, offset); + return (long) layout.varHandle().get((MemorySegment)this, offset); } @ForceInline @Override public void set(ValueLayout.OfLong layout, long offset, long value) { - layout.varHandle().set(this, offset, value); + layout.varHandle().set((MemorySegment)this, offset, value); } @ForceInline @Override public double get(ValueLayout.OfDouble layout, long offset) { - return (double) layout.varHandle().get(this, offset); + return (double) layout.varHandle().get((MemorySegment)this, offset); } @ForceInline @Override public void set(ValueLayout.OfDouble layout, long offset, double value) { - layout.varHandle().set(this, offset, value); + layout.varHandle().set((MemorySegment)this, offset, value); } @ForceInline @Override public MemorySegment get(AddressLayout layout, long offset) { - return (MemorySegment) layout.varHandle().get(this, offset); + return (MemorySegment) layout.varHandle().get((MemorySegment)this, offset); } @ForceInline @Override public void set(AddressLayout layout, long offset, MemorySegment value) { - layout.varHandle().set(this, offset, value); + layout.varHandle().set((MemorySegment)this, offset, value); } @ForceInline @Override public byte getAtIndex(ValueLayout.OfByte layout, long index) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - return (byte) layout.varHandle().get(this, index * layout.byteSize()); + return (byte) layout.varHandle().get((MemorySegment)this, index * layout.byteSize()); } @ForceInline @Override public boolean getAtIndex(ValueLayout.OfBoolean layout, long index) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - return (boolean) layout.varHandle().get(this, index * layout.byteSize()); + return (boolean) layout.varHandle().get((MemorySegment)this, index * layout.byteSize()); } @ForceInline @Override public char getAtIndex(ValueLayout.OfChar layout, long index) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - return (char) layout.varHandle().get(this, index * layout.byteSize()); + return (char) layout.varHandle().get((MemorySegment)this, index * layout.byteSize()); } @ForceInline @Override public void setAtIndex(ValueLayout.OfChar layout, long index, char value) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - layout.varHandle().set(this, index * layout.byteSize(), value); + layout.varHandle().set((MemorySegment)this, index * layout.byteSize(), value); } @ForceInline @Override public short getAtIndex(ValueLayout.OfShort layout, long index) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - return (short) layout.varHandle().get(this, index * layout.byteSize()); + return (short) layout.varHandle().get((MemorySegment)this, index * layout.byteSize()); } @ForceInline @Override public void setAtIndex(ValueLayout.OfByte layout, long index, byte value) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - layout.varHandle().set(this, index * layout.byteSize(), value); + layout.varHandle().set((MemorySegment)this, index * layout.byteSize(), value); } @ForceInline @Override public void setAtIndex(ValueLayout.OfBoolean layout, long index, boolean value) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - layout.varHandle().set(this, index * layout.byteSize(), value); + layout.varHandle().set((MemorySegment)this, index * layout.byteSize(), value); } @ForceInline @Override public void setAtIndex(ValueLayout.OfShort layout, long index, short value) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - layout.varHandle().set(this, index * layout.byteSize(), value); + layout.varHandle().set((MemorySegment)this, index * layout.byteSize(), value); } @ForceInline @Override public int getAtIndex(ValueLayout.OfInt layout, long index) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - return (int) layout.varHandle().get(this, index * layout.byteSize()); + return (int) layout.varHandle().get((MemorySegment)this, index * layout.byteSize()); } @ForceInline @Override public void setAtIndex(ValueLayout.OfInt layout, long index, int value) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - layout.varHandle().set(this, index * layout.byteSize(), value); + layout.varHandle().set((MemorySegment)this, index * layout.byteSize(), value); } @ForceInline @Override public float getAtIndex(ValueLayout.OfFloat layout, long index) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - return (float) layout.varHandle().get(this, index * layout.byteSize()); + return (float) layout.varHandle().get((MemorySegment)this, index * layout.byteSize()); } @ForceInline @Override public void setAtIndex(ValueLayout.OfFloat layout, long index, float value) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - layout.varHandle().set(this, index * layout.byteSize(), value); + layout.varHandle().set((MemorySegment)this, index * layout.byteSize(), value); } @ForceInline @Override public long getAtIndex(ValueLayout.OfLong layout, long index) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - return (long) layout.varHandle().get(this, index * layout.byteSize()); + return (long) layout.varHandle().get((MemorySegment)this, index * layout.byteSize()); } @ForceInline @Override public void setAtIndex(ValueLayout.OfLong layout, long index, long value) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - layout.varHandle().set(this, index * layout.byteSize(), value); + layout.varHandle().set((MemorySegment)this, index * layout.byteSize(), value); } @ForceInline @Override public double getAtIndex(ValueLayout.OfDouble layout, long index) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - return (double) layout.varHandle().get(this, index * layout.byteSize()); + return (double) layout.varHandle().get((MemorySegment)this, index * layout.byteSize()); } @ForceInline @Override public void setAtIndex(ValueLayout.OfDouble layout, long index, double value) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - layout.varHandle().set(this, index * layout.byteSize(), value); + layout.varHandle().set((MemorySegment)this, index * layout.byteSize(), value); } @ForceInline @Override public MemorySegment getAtIndex(AddressLayout layout, long index) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - return (MemorySegment) layout.varHandle().get(this, index * layout.byteSize()); + return (MemorySegment) layout.varHandle().get((MemorySegment)this, index * layout.byteSize()); } @ForceInline @Override public void setAtIndex(AddressLayout layout, long index, MemorySegment value) { Utils.checkElementAlignment(layout, "Layout alignment greater than its size"); - layout.varHandle().set(this, index * layout.byteSize(), value); + layout.varHandle().set((MemorySegment)this, index * layout.byteSize(), value); } @Override diff --git a/test/jdk/java/foreign/TestMemoryAccessInstance.java b/test/jdk/java/foreign/TestMemoryAccessInstance.java index fbcdc5f89b5..a1c774b72dd 100644 --- a/test/jdk/java/foreign/TestMemoryAccessInstance.java +++ b/test/jdk/java/foreign/TestMemoryAccessInstance.java @@ -24,6 +24,7 @@ /* * @test * @run testng/othervm --enable-native-access=ALL-UNNAMED TestMemoryAccessInstance + * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_SEGMENT_FORCE_EXACT=true --enable-native-access=ALL-UNNAMED TestMemoryAccessInstance */ import java.lang.foreign.MemoryLayout;