diff --git a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java index 223e2a9c6d5..c97129bf13d 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java @@ -396,8 +396,8 @@ static Spliterator spliterator(S segment, SequenceL * buffer. The segment starts relative to the buffer's position (inclusive) * and ends relative to the buffer's limit (exclusive). *

- * The segment will feature all access modes, unless the given - * buffer is {@linkplain ByteBuffer#isReadOnly() read-only} in which case the segment will + * The segment will feature all access modes (see {@link #ALL_ACCESS}), + * unless the given buffer is {@linkplain ByteBuffer#isReadOnly() read-only} in which case the segment will * not feature the {@link #WRITE} access mode. *

* The resulting memory segment keeps a reference to the backing buffer, to ensure it remains reachable @@ -414,7 +414,8 @@ static MemorySegment ofByteBuffer(ByteBuffer bb) { * Creates a new array memory segment that models the memory associated with a given heap-allocated byte array. *

* The resulting memory segment keeps a reference to the backing array, to ensure it remains reachable - * for the life-time of the segment. The segment will feature all access modes. + * for the life-time of the segment. The segment will feature all access modes + * (see {@link #ALL_ACCESS}). * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. @@ -427,7 +428,8 @@ static MemorySegment ofArray(byte[] arr) { * Creates a new array memory segment that models the memory associated with a given heap-allocated char array. *

* The resulting memory segment keeps a reference to the backing array, to ensure it remains reachable - * for the life-time of the segment. The segment will feature all access modes. + * for the life-time of the segment. The segment will feature all access modes + * (see {@link #ALL_ACCESS}). * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. @@ -440,7 +442,8 @@ static MemorySegment ofArray(char[] arr) { * Creates a new array memory segment that models the memory associated with a given heap-allocated short array. *

* The resulting memory segment keeps a reference to the backing array, to ensure it remains reachable - * for the life-time of the segment. The segment will feature all access modes. + * for the life-time of the segment. The segment will feature all access modes + * (see {@link #ALL_ACCESS}). * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. @@ -466,7 +469,8 @@ static MemorySegment ofArray(int[] arr) { * Creates a new array memory segment that models the memory associated with a given heap-allocated float array. *

* The resulting memory segment keeps a reference to the backing array, to ensure it remains reachable - * for the life-time of the segment. The segment will feature all access modes. + * for the life-time of the segment. The segment will feature all access modes + * (see {@link #ALL_ACCESS}). * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. @@ -479,7 +483,8 @@ static MemorySegment ofArray(float[] arr) { * Creates a new array memory segment that models the memory associated with a given heap-allocated long array. *

* The resulting memory segment keeps a reference to the backing array, to ensure it remains reachable - * for the life-time of the segment. The segment will feature all access modes. + * for the life-time of the segment. The segment will feature all access modes + * (see {@link #ALL_ACCESS}). * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. @@ -492,7 +497,8 @@ static MemorySegment ofArray(long[] arr) { * Creates a new array memory segment that models the memory associated with a given heap-allocated double array. *

* The resulting memory segment keeps a reference to the backing array, to ensure it remains reachable - * for the life-time of the segment. The segment will feature all access modes. + * for the life-time of the segment. The segment will feature all access modes + * (see {@link #ALL_ACCESS}). * * @param arr the primitive array backing the array memory segment. * @return a new array memory segment. @@ -544,9 +550,9 @@ static MemorySegment allocateNative(long bytesSize) { /** * Creates a new mapped memory segment that models a memory-mapped region of a file from a given path. *

- * The segment will feature all access modes, unless the given mapping mode - * is {@linkplain FileChannel.MapMode#READ_ONLY READ_ONLY}, in which case the segment will not feature - * the {@link #WRITE} access mode. + * The segment will feature all access modes (see {@link #ALL_ACCESS}), + * unless the given mapping mode is {@linkplain FileChannel.MapMode#READ_ONLY READ_ONLY}, in which case + * the segment will not feature the {@link #WRITE} access mode. * * @implNote When obtaining a mapped segment from a newly created file, the initialization state of the contents of the block * of mapped memory associated with the returned mapped memory segment is unspecified and should not be relied upon. @@ -568,7 +574,8 @@ static MappedMemorySegment mapFromPath(Path path, long bytesOffset, long bytesSi /** * Creates a new native memory segment that models a newly allocated block of off-heap memory with given size and - * alignment constraint (in bytes). The segment will feature all access modes. + * alignment constraint (in bytes). The segment will feature all access modes + * (see {@link #ALL_ACCESS}). * * @implNote The block of off-heap memory associated with the returned native memory segment is initialized to zero. * Moreover, a client is responsible to call the {@link MemorySegment#close()} on a native memory segment, @@ -598,7 +605,8 @@ static MemorySegment allocateNative(long bytesSize, long alignmentBytes) { * bounds, and can therefore be closed; closing such a segment can optionally result in calling an user-provided cleanup * action. This method can be very useful when interacting with custom native memory sources (e.g. custom allocators, * GPU memory, etc.), where an address to some underlying memory region is typically obtained from native code - * (often as a plain {@code long} value). The segment will feature all access modes. + * (often as a plain {@code long} value). The segment will feature all access modes + * (see {@link #ALL_ACCESS}). *

* This method is restricted. Restricted method are unsafe, and, if used incorrectly, their use might crash * the JVM crash or, worse, silently result in memory corruption. Thus, clients should refrain from depending on @@ -666,4 +674,11 @@ static MemorySegment ofNativeRestricted(MemoryAddress addr, long bytesSize, Thre * @see MemorySegment#withAccessModes(int) */ int HANDOFF = ACQUIRE << 1; + + /** + * Default access mode; this is a union of all the access modes supported by memory segments. + * @see MemorySegment#accessModes() + * @see MemorySegment#withAccessModes(int) + */ + int ALL_ACCESS = READ | WRITE | CLOSE | ACQUIRE | HANDOFF; } diff --git a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java index 2f804184494..2bfe7926e8d 100644 --- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java +++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java @@ -64,11 +64,9 @@ public abstract class AbstractMemorySegmentImpl implements MemorySegment, Memory private static final boolean enableSmallSegments = Boolean.parseBoolean(GetPropertyAction.privilegedGetProperty("jdk.incubator.foreign.SmallSegments", "true")); - final static int ACCESS_MASK = READ | WRITE | CLOSE | ACQUIRE | HANDOFF; final static int FIRST_RESERVED_FLAG = 1 << 16; // upper 16 bits are reserved final static int SMALL = FIRST_RESERVED_FLAG; final static long NONCE = new Random().nextLong(); - final static int DEFAULT_MASK = READ | WRITE | CLOSE | ACQUIRE | HANDOFF; final static JavaNioAccess nioAccess = SharedSecrets.getJavaNioAccess(); @@ -93,8 +91,8 @@ public abstract class AbstractMemorySegmentImpl implements MemorySegment, Memory static int defaultAccessModes(long size) { return (enableSmallSegments && size < Integer.MAX_VALUE) ? - DEFAULT_MASK | SMALL : - DEFAULT_MASK; + ALL_ACCESS | SMALL : + ALL_ACCESS; } @Override @@ -192,7 +190,7 @@ public final ByteBuffer asByteBuffer() { @Override public final int accessModes() { - return mask & ACCESS_MASK; + return mask & ALL_ACCESS; } @Override @@ -216,7 +214,7 @@ public AbstractMemorySegmentImpl withAccessModes(int accessModes) { if ((~accessModes() & accessModes) != 0) { throw new IllegalArgumentException("Cannot acquire more access modes"); } - return dup(0, length, (mask & ~ACCESS_MASK) | accessModes, scope); + return dup(0, length, (mask & ~ALL_ACCESS) | accessModes, scope); } @Override @@ -226,7 +224,7 @@ public boolean hasAccessModes(int accessModes) { } private void checkAccessModes(int accessModes) { - if ((accessModes & ~ACCESS_MASK) != 0) { + if ((accessModes & ~ALL_ACCESS) != 0) { throw new IllegalArgumentException("Invalid access modes"); } } diff --git a/test/jdk/java/foreign/TestByteBuffer.java b/test/jdk/java/foreign/TestByteBuffer.java index ef6b0098047..984763907a6 100644 --- a/test/jdk/java/foreign/TestByteBuffer.java +++ b/test/jdk/java/foreign/TestByteBuffer.java @@ -239,18 +239,16 @@ public void testChannel() throws Throwable { } } - static final int ALL_ACCESS_MODES = READ | WRITE | CLOSE | ACQUIRE | HANDOFF; - @Test public void testDefaultAccessModesMappedSegment() throws Throwable { try (MappedMemorySegment segment = MemorySegment.mapFromPath(tempPath, 0L, 8, FileChannel.MapMode.READ_WRITE)) { - assertTrue(segment.hasAccessModes(ALL_ACCESS_MODES)); - assertEquals(segment.accessModes(), ALL_ACCESS_MODES); + assertTrue(segment.hasAccessModes(ALL_ACCESS)); + assertEquals(segment.accessModes(), ALL_ACCESS); } try (MappedMemorySegment segment = MemorySegment.mapFromPath(tempPath, 0L, 8, FileChannel.MapMode.READ_ONLY)) { - assertTrue(segment.hasAccessModes(ALL_ACCESS_MODES & ~WRITE)); - assertEquals(segment.accessModes(), ALL_ACCESS_MODES& ~WRITE); + assertTrue(segment.hasAccessModes(ALL_ACCESS & ~WRITE)); + assertEquals(segment.accessModes(), ALL_ACCESS & ~WRITE); } } @@ -521,14 +519,14 @@ public void testCopyNativeToHeap(Consumer checker, Consumer bufferFunction, int } } - static final int ALL_ACCESS_MODES = READ | WRITE | CLOSE | ACQUIRE | HANDOFF; - @Test public void testDefaultAccessModes() { MemoryAddress addr = MemoryAddress.ofLong(allocate(12)); MemorySegment mallocSegment = MemorySegment.ofNativeRestricted(addr, 12, null, () -> free(addr.toRawLongValue()), null); try (MemorySegment segment = mallocSegment) { - assertTrue(segment.hasAccessModes(ALL_ACCESS_MODES)); - assertEquals(segment.accessModes(), ALL_ACCESS_MODES); + assertTrue(segment.hasAccessModes(ALL_ACCESS)); + assertEquals(segment.accessModes(), ALL_ACCESS); } } diff --git a/test/jdk/java/foreign/TestSegments.java b/test/jdk/java/foreign/TestSegments.java index 8da9ae55519..ffd8a1cd2b4 100644 --- a/test/jdk/java/foreign/TestSegments.java +++ b/test/jdk/java/foreign/TestSegments.java @@ -146,13 +146,11 @@ public void testSlices() { } } - static final int ALL_ACCESS_MODES = READ | WRITE | CLOSE | ACQUIRE | HANDOFF; - @Test(dataProvider = "segmentFactories") public void testAccessModesOfFactories(Supplier memorySegmentSupplier) { try (MemorySegment segment = memorySegmentSupplier.get()) { - assertTrue(segment.hasAccessModes(ALL_ACCESS_MODES)); - assertEquals(segment.accessModes(), ALL_ACCESS_MODES); + assertTrue(segment.hasAccessModes(ALL_ACCESS)); + assertEquals(segment.accessModes(), ALL_ACCESS); } } diff --git a/test/jdk/java/foreign/TestSpliterator.java b/test/jdk/java/foreign/TestSpliterator.java index 9ebc9a2e504..f0922b23ef3 100644 --- a/test/jdk/java/foreign/TestSpliterator.java +++ b/test/jdk/java/foreign/TestSpliterator.java @@ -205,15 +205,13 @@ public Object[][] splits() { }; } - static final int ALL_ACCESS_MODES = READ | WRITE | CLOSE | ACQUIRE | HANDOFF; - @DataProvider(name = "accessScenarios") public Object[][] accessScenarios() { SequenceLayout layout = MemoryLayout.ofSequence(16, MemoryLayouts.JAVA_INT); var mallocSegment = MemorySegment.allocateNative(layout); Map>,Integer> l = Map.of( - () -> spliterator(mallocSegment.withAccessModes(ALL_ACCESS_MODES), layout), ALL_ACCESS_MODES, + () -> spliterator(mallocSegment.withAccessModes(ALL_ACCESS), layout), ALL_ACCESS, () -> spliterator(mallocSegment.withAccessModes(0), layout), 0, () -> spliterator(mallocSegment.withAccessModes(READ), layout), READ, () -> spliterator(mallocSegment.withAccessModes(CLOSE), layout), 0,