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
|