< prev index next > src/java.base/share/classes/jdk/internal/foreign/NativeMemorySegmentImpl.java
Print this page
import java.util.Optional;
import jdk.internal.misc.Unsafe;
import jdk.internal.misc.VM;
import jdk.internal.vm.annotation.ForceInline;
- import sun.security.action.GetBooleanAction;
/**
* Implementation for native memory segments. A native memory segment is essentially a wrapper around
* a native long address.
*/
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
// The maximum alignment supported by malloc - typically 16 bytes on
// 64-bit platforms and 8 bytes on 32-bit platforms.
private static final long MAX_MALLOC_ALIGN = Unsafe.ADDRESS_SIZE == 4 ? 8 : 16;
- private static final boolean SKIP_ZERO_MEMORY = GetBooleanAction.privilegedGetProperty("jdk.internal.foreign.skipZeroMemory");
final long min;
@ForceInline
NativeMemorySegmentImpl(long min, long length, boolean readOnly, MemorySessionImpl scope) {
return 0;
}
// factories
! public static MemorySegment makeNativeSegment(long byteSize, long byteAlignment, MemorySessionImpl sessionImpl) {
sessionImpl.checkValidState();
if (VM.isDirectMemoryPageAligned()) {
byteAlignment = Math.max(byteAlignment, NIO_ACCESS.pageSize());
}
long alignedSize = Math.max(1L, byteAlignment > MAX_MALLOC_ALIGN ?
byteSize + (byteAlignment - 1) :
byteSize);
! NIO_ACCESS.reserveMemory(alignedSize, byteSize);
!
- long buf = UNSAFE.allocateMemory(alignedSize);
- if (!SKIP_ZERO_MEMORY) {
- UNSAFE.setMemory(buf, alignedSize, (byte)0);
}
long alignedBuf = Utils.alignUp(buf, byteAlignment);
AbstractMemorySegmentImpl segment = new NativeMemorySegmentImpl(buf, alignedSize,
false, sessionImpl);
sessionImpl.addOrCleanupIfFail(new MemorySessionImpl.ResourceList.ResourceCleanup() {
@Override
public void cleanup() {
UNSAFE.freeMemory(buf);
! NIO_ACCESS.unreserveMemory(alignedSize, byteSize);
}
});
if (alignedSize != byteSize) {
long delta = alignedBuf - buf;
segment = segment.asSlice(delta, byteSize);
}
return segment;
}
// Unsafe native segment factories. These are used by the implementation code, to skip the sanity checks
// associated with MemorySegment::ofAddress.
@ForceInline
public static MemorySegment makeNativeSegmentUnchecked(long min, long byteSize, MemorySessionImpl sessionImpl, Runnable action) {
return 0;
}
// factories
! public static MemorySegment makeNativeSegment(long byteSize, long byteAlignment, MemorySessionImpl sessionImpl,
+ boolean shouldReserve) {
sessionImpl.checkValidState();
if (VM.isDirectMemoryPageAligned()) {
byteAlignment = Math.max(byteAlignment, NIO_ACCESS.pageSize());
}
long alignedSize = Math.max(1L, byteAlignment > MAX_MALLOC_ALIGN ?
byteSize + (byteAlignment - 1) :
byteSize);
! if (shouldReserve) {
! NIO_ACCESS.reserveMemory(alignedSize, byteSize);
}
+
+ long buf = allocateMemoryWrapper(alignedSize);
long alignedBuf = Utils.alignUp(buf, byteAlignment);
AbstractMemorySegmentImpl segment = new NativeMemorySegmentImpl(buf, alignedSize,
false, sessionImpl);
sessionImpl.addOrCleanupIfFail(new MemorySessionImpl.ResourceList.ResourceCleanup() {
@Override
public void cleanup() {
UNSAFE.freeMemory(buf);
! if (shouldReserve) {
+ NIO_ACCESS.unreserveMemory(alignedSize, byteSize);
+ }
}
});
if (alignedSize != byteSize) {
long delta = alignedBuf - buf;
segment = segment.asSlice(delta, byteSize);
}
return segment;
}
+ private static long allocateMemoryWrapper(long size) {
+ try {
+ return UNSAFE.allocateMemory(size);
+ } catch (IllegalArgumentException ex) {
+ throw new OutOfMemoryError();
+ }
+ }
+
// Unsafe native segment factories. These are used by the implementation code, to skip the sanity checks
// associated with MemorySegment::ofAddress.
@ForceInline
public static MemorySegment makeNativeSegmentUnchecked(long min, long byteSize, MemorySessionImpl sessionImpl, Runnable action) {
< prev index next >