Skip to content
Permalink
Browse files
8246053: Add a mask for default access modesAdd a default access mode…
… flag

Reviewed-by: sundar, chegar
  • Loading branch information
mcimadamore committed May 28, 2020
1 parent 648b843 commit fee6f89ebaa2c8695e0c059f30e17ea710308af1
@@ -396,8 +396,8 @@
* buffer. The segment starts relative to the buffer's position (inclusive)
* and ends relative to the buffer's limit (exclusive).
* <p>
* The segment will feature all <a href="#access-modes">access modes</a>, unless the given
* buffer is {@linkplain ByteBuffer#isReadOnly() read-only} in which case the segment will
* The segment will feature all <a href="#access-modes">access modes</a> (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.
* <p>
* The resulting memory segment keeps a reference to the backing buffer, to ensure it remains <em>reachable</em>
@@ -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.
* <p>
* The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
* for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>.
* for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>
* (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.
* <p>
* The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
* for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>.
* for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>
* (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.
* <p>
* The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
* for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>.
* for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>
* (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.
* <p>
* The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
* for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>.
* for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>
* (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.
* <p>
* The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
* for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>.
* for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>
* (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.
* <p>
* The resulting memory segment keeps a reference to the backing array, to ensure it remains <em>reachable</em>
* for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>.
* for the life-time of the segment. The segment will feature all <a href="#access-modes">access modes</a>
* (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.
* <p>
* The segment will feature all <a href="#access-modes">access modes</a>, 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 <a href="#access-modes">access modes</a> (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 <a href="#access-modes">access modes</a>.
* alignment constraint (in bytes). The segment will feature all <a href="#access-modes">access modes</a>
* (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 <a href="#access-modes">access modes</a>.
* (often as a plain {@code long} value). The segment will feature all <a href="#access-modes">access modes</a>
* (see {@link #ALL_ACCESS}).
* <p>
* This method is <em>restricted</em>. 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;
}
@@ -64,11 +64,9 @@
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 @@

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");
}
}
@@ -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<MemoryAddress> checker, Consumer<Memor
public void testDefaultAccessModesOfBuffer() {
ByteBuffer rwBuffer = ByteBuffer.wrap(new byte[4]);
try (MemorySegment segment = MemorySegment.ofByteBuffer(rwBuffer)) {
assertTrue(segment.hasAccessModes(ALL_ACCESS_MODES));
assertEquals(segment.accessModes(), ALL_ACCESS_MODES);
assertTrue(segment.hasAccessModes(ALL_ACCESS));
assertEquals(segment.accessModes(), ALL_ACCESS);
}

ByteBuffer roBuffer = rwBuffer.asReadOnlyBuffer();
try (MemorySegment segment = MemorySegment.ofByteBuffer(roBuffer)) {
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);
}
}

@@ -172,16 +172,14 @@ public void testNativeCapacity(Function<ByteBuffer, Buffer> 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);
}
}

@@ -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<MemorySegment> 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);
}
}

@@ -205,15 +205,13 @@ protected Long compute() {
};
}

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<Supplier<Spliterator<MemorySegment>>,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,

0 comments on commit fee6f89

Please sign in to comment.