< prev index next >

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

Print this page

 16  *
 17  *  You should have received a copy of the GNU General Public License version
 18  *  2 along with this work; if not, write to the Free Software Foundation,
 19  *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  *   Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  *  or visit www.oracle.com if you need additional information or have any
 23  *  questions.
 24  *
 25  */
 26 
 27 package jdk.internal.foreign;
 28 
 29 import java.lang.foreign.MemorySegment;
 30 import java.nio.ByteBuffer;
 31 import java.util.Optional;
 32 
 33 import jdk.internal.misc.Unsafe;
 34 import jdk.internal.misc.VM;
 35 import jdk.internal.vm.annotation.ForceInline;
 36 import sun.security.action.GetBooleanAction;
 37 
 38 /**
 39  * Implementation for native memory segments. A native memory segment is essentially a wrapper around
 40  * a native long address.
 41  */
 42 public sealed class NativeMemorySegmentImpl extends AbstractMemorySegmentImpl permits MappedMemorySegmentImpl {
 43 
 44     private static final Unsafe UNSAFE = Unsafe.getUnsafe();
 45 
 46     // The maximum alignment supported by malloc - typically 16 bytes on
 47     // 64-bit platforms and 8 bytes on 32-bit platforms.
 48     private static final long MAX_MALLOC_ALIGN = Unsafe.ADDRESS_SIZE == 4 ? 8 : 16;
 49     private static final boolean SKIP_ZERO_MEMORY = GetBooleanAction.privilegedGetProperty("jdk.internal.foreign.skipZeroMemory");
 50 
 51     final long min;
 52 
 53     @ForceInline
 54     NativeMemorySegmentImpl(long min, long length, boolean readOnly, MemorySessionImpl scope) {
 55         super(length, readOnly, scope);
 56         this.min = (Unsafe.getUnsafe().addressSize() == 4)
 57                 // On 32-bit systems, normalize the upper unused 32-bits to zero
 58                 ? min & 0x0000_0000_FFFF_FFFFL
 59                 // On 64-bit systems, all the bits are used
 60                 : min;
 61     }
 62 
 63     /**
 64      * This constructor should only be used when initializing {@link MemorySegment#NULL}. Note: because of the memory
 65      * segment class hierarchy, it is possible to end up in a situation where this constructor is called
 66      * when the static fields in this class are not yet initialized.
 67      */
 68     @ForceInline
 69     public NativeMemorySegmentImpl() {

 98         return true;
 99     }
100 
101     @Override
102     public long unsafeGetOffset() {
103         return min;
104     }
105 
106     @Override
107     public Object unsafeGetBase() {
108         return null;
109     }
110 
111     @Override
112     public long maxAlignMask() {
113         return 0;
114     }
115 
116     // factories
117 
118     public static MemorySegment makeNativeSegment(long byteSize, long byteAlignment, MemorySessionImpl sessionImpl) {

119         sessionImpl.checkValidState();
120         if (VM.isDirectMemoryPageAligned()) {
121             byteAlignment = Math.max(byteAlignment, NIO_ACCESS.pageSize());
122         }
123         long alignedSize = Math.max(1L, byteAlignment > MAX_MALLOC_ALIGN ?
124                 byteSize + (byteAlignment - 1) :
125                 byteSize);
126 
127         NIO_ACCESS.reserveMemory(alignedSize, byteSize);
128 
129         long buf = UNSAFE.allocateMemory(alignedSize);
130         if (!SKIP_ZERO_MEMORY) {
131             UNSAFE.setMemory(buf, alignedSize, (byte)0);
132         }


133         long alignedBuf = Utils.alignUp(buf, byteAlignment);
134         AbstractMemorySegmentImpl segment = new NativeMemorySegmentImpl(buf, alignedSize,
135                 false, sessionImpl);
136         sessionImpl.addOrCleanupIfFail(new MemorySessionImpl.ResourceList.ResourceCleanup() {
137             @Override
138             public void cleanup() {
139                 UNSAFE.freeMemory(buf);
140                 NIO_ACCESS.unreserveMemory(alignedSize, byteSize);


141             }
142         });
143         if (alignedSize != byteSize) {
144             long delta = alignedBuf - buf;
145             segment = segment.asSlice(delta, byteSize);
146         }
147         return segment;
148     }
149 








150     // Unsafe native segment factories. These are used by the implementation code, to skip the sanity checks
151     // associated with MemorySegment::ofAddress.
152 
153     @ForceInline
154     public static MemorySegment makeNativeSegmentUnchecked(long min, long byteSize, MemorySessionImpl sessionImpl, Runnable action) {
155         if (action == null) {
156             sessionImpl.checkValidState();
157         } else {
158             sessionImpl.addCloseAction(action);
159         }
160         return new NativeMemorySegmentImpl(min, byteSize, false, sessionImpl);
161     }
162 
163     @ForceInline
164     public static MemorySegment makeNativeSegmentUnchecked(long min, long byteSize, MemorySessionImpl sessionImpl) {
165         sessionImpl.checkValidState();
166         return new NativeMemorySegmentImpl(min, byteSize, false, sessionImpl);
167     }
168 
169     @ForceInline

 16  *
 17  *  You should have received a copy of the GNU General Public License version
 18  *  2 along with this work; if not, write to the Free Software Foundation,
 19  *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  *   Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  *  or visit www.oracle.com if you need additional information or have any
 23  *  questions.
 24  *
 25  */
 26 
 27 package jdk.internal.foreign;
 28 
 29 import java.lang.foreign.MemorySegment;
 30 import java.nio.ByteBuffer;
 31 import java.util.Optional;
 32 
 33 import jdk.internal.misc.Unsafe;
 34 import jdk.internal.misc.VM;
 35 import jdk.internal.vm.annotation.ForceInline;

 36 
 37 /**
 38  * Implementation for native memory segments. A native memory segment is essentially a wrapper around
 39  * a native long address.
 40  */
 41 public sealed class NativeMemorySegmentImpl extends AbstractMemorySegmentImpl permits MappedMemorySegmentImpl {
 42 
 43     private static final Unsafe UNSAFE = Unsafe.getUnsafe();
 44 
 45     // The maximum alignment supported by malloc - typically 16 bytes on
 46     // 64-bit platforms and 8 bytes on 32-bit platforms.
 47     private static final long MAX_MALLOC_ALIGN = Unsafe.ADDRESS_SIZE == 4 ? 8 : 16;

 48 
 49     final long min;
 50 
 51     @ForceInline
 52     NativeMemorySegmentImpl(long min, long length, boolean readOnly, MemorySessionImpl scope) {
 53         super(length, readOnly, scope);
 54         this.min = (Unsafe.getUnsafe().addressSize() == 4)
 55                 // On 32-bit systems, normalize the upper unused 32-bits to zero
 56                 ? min & 0x0000_0000_FFFF_FFFFL
 57                 // On 64-bit systems, all the bits are used
 58                 : min;
 59     }
 60 
 61     /**
 62      * This constructor should only be used when initializing {@link MemorySegment#NULL}. Note: because of the memory
 63      * segment class hierarchy, it is possible to end up in a situation where this constructor is called
 64      * when the static fields in this class are not yet initialized.
 65      */
 66     @ForceInline
 67     public NativeMemorySegmentImpl() {

 96         return true;
 97     }
 98 
 99     @Override
100     public long unsafeGetOffset() {
101         return min;
102     }
103 
104     @Override
105     public Object unsafeGetBase() {
106         return null;
107     }
108 
109     @Override
110     public long maxAlignMask() {
111         return 0;
112     }
113 
114     // factories
115 
116     public static MemorySegment makeNativeSegment(long byteSize, long byteAlignment, MemorySessionImpl sessionImpl,
117                                                   boolean shouldReserve) {
118         sessionImpl.checkValidState();
119         if (VM.isDirectMemoryPageAligned()) {
120             byteAlignment = Math.max(byteAlignment, NIO_ACCESS.pageSize());
121         }
122         long alignedSize = Math.max(1L, byteAlignment > MAX_MALLOC_ALIGN ?
123                 byteSize + (byteAlignment - 1) :
124                 byteSize);
125 
126         if (shouldReserve) {
127             NIO_ACCESS.reserveMemory(alignedSize, byteSize);



128         }
129 
130         long buf = allocateMemoryWrapper(alignedSize);
131         long alignedBuf = Utils.alignUp(buf, byteAlignment);
132         AbstractMemorySegmentImpl segment = new NativeMemorySegmentImpl(buf, alignedSize,
133                 false, sessionImpl);
134         sessionImpl.addOrCleanupIfFail(new MemorySessionImpl.ResourceList.ResourceCleanup() {
135             @Override
136             public void cleanup() {
137                 UNSAFE.freeMemory(buf);
138                 if (shouldReserve) {
139                     NIO_ACCESS.unreserveMemory(alignedSize, byteSize);
140                 }
141             }
142         });
143         if (alignedSize != byteSize) {
144             long delta = alignedBuf - buf;
145             segment = segment.asSlice(delta, byteSize);
146         }
147         return segment;
148     }
149 
150     private static long allocateMemoryWrapper(long size) {
151         try {
152             return UNSAFE.allocateMemory(size);
153         } catch (IllegalArgumentException ex) {
154             throw new OutOfMemoryError();
155         }
156     }
157 
158     // Unsafe native segment factories. These are used by the implementation code, to skip the sanity checks
159     // associated with MemorySegment::ofAddress.
160 
161     @ForceInline
162     public static MemorySegment makeNativeSegmentUnchecked(long min, long byteSize, MemorySessionImpl sessionImpl, Runnable action) {
163         if (action == null) {
164             sessionImpl.checkValidState();
165         } else {
166             sessionImpl.addCloseAction(action);
167         }
168         return new NativeMemorySegmentImpl(min, byteSize, false, sessionImpl);
169     }
170 
171     @ForceInline
172     public static MemorySegment makeNativeSegmentUnchecked(long min, long byteSize, MemorySessionImpl sessionImpl) {
173         sessionImpl.checkValidState();
174         return new NativeMemorySegmentImpl(min, byteSize, false, sessionImpl);
175     }
176 
177     @ForceInline
< prev index next >