< prev index next >

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

Print this page
*** 31,10 ***
--- 31,12 ---
  import java.lang.foreign.MemorySegment.Scope;
  import java.lang.invoke.MethodHandles;
  import java.lang.invoke.VarHandle;
  import java.lang.ref.Cleaner;
  import java.util.Objects;
+ 
+ import jdk.internal.foreign.GlobalSession.HeapSession;
  import jdk.internal.misc.ScopedMemoryAccess;
  import jdk.internal.vm.annotation.ForceInline;
  
  /**
   * This class manages the temporal bounds associated with a memory segment as well

*** 57,14 ***
      static final int CLOSED = -2;
  
      static final VarHandle STATE;
      static final int MAX_FORKS = Integer.MAX_VALUE;
  
-     public static final MemorySessionImpl GLOBAL = new GlobalSession(null);
- 
      static final ScopedMemoryAccess.ScopedAccessError ALREADY_CLOSED = new ScopedMemoryAccess.ScopedAccessError(MemorySessionImpl::alreadyClosed);
      static final ScopedMemoryAccess.ScopedAccessError WRONG_THREAD = new ScopedMemoryAccess.ScopedAccessError(MemorySessionImpl::wrongThread);
  
      final ResourceList resourceList;
      final Thread owner;
      int state = OPEN;
  
--- 59,14 ---
      static final int CLOSED = -2;
  
      static final VarHandle STATE;
      static final int MAX_FORKS = Integer.MAX_VALUE;
  
      static final ScopedMemoryAccess.ScopedAccessError ALREADY_CLOSED = new ScopedMemoryAccess.ScopedAccessError(MemorySessionImpl::alreadyClosed);
      static final ScopedMemoryAccess.ScopedAccessError WRONG_THREAD = new ScopedMemoryAccess.ScopedAccessError(MemorySessionImpl::wrongThread);
+     // This is the session of all zero-length memory segments
+     static final GlobalSession NATIVE_SESSION = new GlobalSession();
  
      final ResourceList resourceList;
      final Thread owner;
      int state = OPEN;
  

*** 75,25 ***
              throw new ExceptionInInitializerError(ex);
          }
      }
  
      public Arena asArena() {
!         return new Arena() {
-             @Override
-             public Scope scope() {
-                 return MemorySessionImpl.this;
-             }
- 
-             @Override
-             public void close() {
-                 MemorySessionImpl.this.close();
-             }
-         };
      }
  
      @ForceInline
!     public static final MemorySessionImpl toMemorySession(Arena arena) {
          return (MemorySessionImpl) arena.scope();
      }
  
      public final boolean isCloseableBy(Thread thread) {
          Objects.requireNonNull(thread);
--- 77,15 ---
              throw new ExceptionInInitializerError(ex);
          }
      }
  
      public Arena asArena() {
!         return new ArenaImpl(this);
      }
  
      @ForceInline
!     public static MemorySessionImpl toMemorySession(Arena arena) {
          return (MemorySessionImpl) arena.scope();
      }
  
      public final boolean isCloseableBy(Thread thread) {
          Objects.requireNonNull(thread);

*** 105,14 ***
          Objects.requireNonNull(runnable);
          addInternal(ResourceList.ResourceCleanup.ofRunnable(runnable));
      }
  
      /**
!      * Add a cleanup action. If a failure occurred (because of a add vs. close race), call the cleanup action.
       * This semantics is useful when allocating new memory segments, since we first do a malloc/mmap and _then_
       * we register the cleanup (free/munmap) against the session; so, if registration fails, we still have to
!      * cleanup memory. From the perspective of the client, such a failure would manifest as a factory
       * returning a segment that is already "closed" - which is always possible anyway (e.g. if the session
       * is closed _after_ the cleanup for the segment is registered but _before_ the factory returns the
       * new segment to the client). For this reason, it's not worth adding extra complexity to the segment
       * initialization logic here - and using an optimistic logic works well in practice.
       */
--- 97,14 ---
          Objects.requireNonNull(runnable);
          addInternal(ResourceList.ResourceCleanup.ofRunnable(runnable));
      }
  
      /**
!      * Add a cleanup action. If a failure occurred (because of an add vs. close race), call the cleanup action.
       * This semantics is useful when allocating new memory segments, since we first do a malloc/mmap and _then_
       * we register the cleanup (free/munmap) against the session; so, if registration fails, we still have to
!      * clean up memory. From the perspective of the client, such a failure would manifest as a factory
       * returning a segment that is already "closed" - which is always possible anyway (e.g. if the session
       * is closed _after_ the cleanup for the segment is registered but _before_ the factory returns the
       * new segment to the client). For this reason, it's not worth adding extra complexity to the segment
       * initialization logic here - and using an optimistic logic works well in practice.
       */

*** 151,13 ***
  
      public static MemorySessionImpl createImplicit(Cleaner cleaner) {
          return new ImplicitSession(cleaner);
      }
  
!     public MemorySegment allocate(long byteSize, long byteAlignment) {
!         Utils.checkAllocationSizeAndAlign(byteSize, byteAlignment);
!         return NativeMemorySegmentImpl.makeNativeSegment(byteSize, byteAlignment, this);
      }
  
      public abstract void release0();
  
      public abstract void acquire0();
--- 143,16 ---
  
      public static MemorySessionImpl createImplicit(Cleaner cleaner) {
          return new ImplicitSession(cleaner);
      }
  
!     public static MemorySessionImpl createGlobal() {
!         return new GlobalSession();
!     }
+ 
+     public static MemorySessionImpl createHeap(Object ref) {
+         return new HeapSession(ref);
      }
  
      public abstract void release0();
  
      public abstract void acquire0();

*** 208,21 ***
      }
  
      /**
       * Checks that this session is still alive (see {@link #isAlive()}).
       * @throws IllegalStateException if this session is already closed or if this is
!      * a confined session and this method is called outside of the owner thread.
       */
      public void checkValidState() {
          try {
              checkValidStateRaw();
          } catch (ScopedMemoryAccess.ScopedAccessError error) {
              throw error.newRuntimeException();
          }
      }
  
!     public static final void checkValidState(MemorySegment segment) {
          ((AbstractMemorySegmentImpl)segment).sessionImpl().checkValidState();
      }
  
      @Override
      protected Object clone() throws CloneNotSupportedException {
--- 203,21 ---
      }
  
      /**
       * Checks that this session is still alive (see {@link #isAlive()}).
       * @throws IllegalStateException if this session is already closed or if this is
!      * a confined session and this method is called outside the owner thread.
       */
      public void checkValidState() {
          try {
              checkValidStateRaw();
          } catch (ScopedMemoryAccess.ScopedAccessError error) {
              throw error.newRuntimeException();
          }
      }
  
!     public static void checkValidState(MemorySegment segment) {
          ((AbstractMemorySegmentImpl)segment).sessionImpl().checkValidState();
      }
  
      @Override
      protected Object clone() throws CloneNotSupportedException {

*** 234,23 ***
      }
  
      /**
       * Closes this session, executing any cleanup action (where provided).
       * @throws IllegalStateException if this session is already closed or if this is
!      * a confined session and this method is called outside of the owner thread.
       */
      public void close() {
          justClose();
          resourceList.cleanup();
      }
  
      abstract void justClose();
  
-     public static MemorySessionImpl heapSession(Object ref) {
-         return new GlobalSession(ref);
-     }
- 
      /**
       * A list of all cleanup actions associated with a memory session. Cleanup actions are modelled as instances
       * of the {@link ResourceCleanup} class, and, together, form a linked list. Depending on whether a session
       * is shared or confined, different implementations of this class will be used, see {@link ConfinedSession.ConfinedResourceList}
       * and {@link SharedSession.SharedResourceList}.
--- 229,19 ---
      }
  
      /**
       * Closes this session, executing any cleanup action (where provided).
       * @throws IllegalStateException if this session is already closed or if this is
!      * a confined session and this method is called outside the owner thread.
       */
      public void close() {
          justClose();
          resourceList.cleanup();
      }
  
      abstract void justClose();
  
      /**
       * A list of all cleanup actions associated with a memory session. Cleanup actions are modelled as instances
       * of the {@link ResourceCleanup} class, and, together, form a linked list. Depending on whether a session
       * is shared or confined, different implementations of this class will be used, see {@link ConfinedSession.ConfinedResourceList}
       * and {@link SharedSession.SharedResourceList}.
< prev index next >