< prev index next >

src/java.base/share/classes/jdk/internal/foreign/NativeMemorySegmentImpl.java

Print this page
@@ -31,11 +31,10 @@
  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.
   */

@@ -44,11 +43,10 @@
      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) {

@@ -113,42 +111,52 @@
          return 0;
      }
  
      // factories
  
-     public static MemorySegment makeNativeSegment(long byteSize, long byteAlignment, MemorySessionImpl sessionImpl) {
+     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);
  
-         NIO_ACCESS.reserveMemory(alignedSize, byteSize);
- 
-         long buf = UNSAFE.allocateMemory(alignedSize);
-         if (!SKIP_ZERO_MEMORY) {
-             UNSAFE.setMemory(buf, alignedSize, (byte)0);
+         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);
-                 NIO_ACCESS.unreserveMemory(alignedSize, byteSize);
+                 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 >