< prev index next >

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

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

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

*** 113,42 ***
          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) {
--- 111,52 ---
          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 >