Skip to content

Commit 8792844

Browse files
mcimadamoreJornVernee
authored andcommitted
8317514: Ensure MemorySegment is initialized before touching NativeMemorySegmentImpl
Co-authored-by: Jorn Vernee <[email protected]> Reviewed-by: jvernee
1 parent 03a8ea3 commit 8792844

File tree

12 files changed

+338
-183
lines changed

12 files changed

+338
-183
lines changed

src/java.base/share/classes/java/lang/foreign/MemorySegment.java

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,8 @@
4444
import java.util.function.Consumer;
4545
import java.util.stream.Stream;
4646
import jdk.internal.foreign.AbstractMemorySegmentImpl;
47-
import jdk.internal.foreign.HeapMemorySegmentImpl;
4847
import jdk.internal.foreign.MemorySessionImpl;
49-
import jdk.internal.foreign.NativeMemorySegmentImpl;
48+
import jdk.internal.foreign.SegmentFactories;
5049
import jdk.internal.foreign.StringSupport;
5150
import jdk.internal.foreign.Utils;
5251
import jdk.internal.javac.Restricted;
@@ -1203,7 +1202,7 @@ static MemorySegment ofBuffer(Buffer buffer) {
12031202
* @return a heap memory segment backed by a byte array.
12041203
*/
12051204
static MemorySegment ofArray(byte[] byteArray) {
1206-
return HeapMemorySegmentImpl.OfByte.fromArray(byteArray);
1205+
return SegmentFactories.fromArray(byteArray);
12071206
}
12081207

12091208
/**
@@ -1215,7 +1214,7 @@ static MemorySegment ofArray(byte[] byteArray) {
12151214
* @return a heap memory segment backed by a char array.
12161215
*/
12171216
static MemorySegment ofArray(char[] charArray) {
1218-
return HeapMemorySegmentImpl.OfChar.fromArray(charArray);
1217+
return SegmentFactories.fromArray(charArray);
12191218
}
12201219

12211220
/**
@@ -1227,7 +1226,7 @@ static MemorySegment ofArray(char[] charArray) {
12271226
* @return a heap memory segment backed by a short array.
12281227
*/
12291228
static MemorySegment ofArray(short[] shortArray) {
1230-
return HeapMemorySegmentImpl.OfShort.fromArray(shortArray);
1229+
return SegmentFactories.fromArray(shortArray);
12311230
}
12321231

12331232
/**
@@ -1239,7 +1238,7 @@ static MemorySegment ofArray(short[] shortArray) {
12391238
* @return a heap memory segment backed by an int array.
12401239
*/
12411240
static MemorySegment ofArray(int[] intArray) {
1242-
return HeapMemorySegmentImpl.OfInt.fromArray(intArray);
1241+
return SegmentFactories.fromArray(intArray);
12431242
}
12441243

12451244
/**
@@ -1251,7 +1250,7 @@ static MemorySegment ofArray(int[] intArray) {
12511250
* @return a heap memory segment backed by a float array.
12521251
*/
12531252
static MemorySegment ofArray(float[] floatArray) {
1254-
return HeapMemorySegmentImpl.OfFloat.fromArray(floatArray);
1253+
return SegmentFactories.fromArray(floatArray);
12551254
}
12561255

12571256
/**
@@ -1263,7 +1262,7 @@ static MemorySegment ofArray(float[] floatArray) {
12631262
* @return a heap memory segment backed by a long array.
12641263
*/
12651264
static MemorySegment ofArray(long[] longArray) {
1266-
return HeapMemorySegmentImpl.OfLong.fromArray(longArray);
1265+
return SegmentFactories.fromArray(longArray);
12671266
}
12681267

12691268
/**
@@ -1275,13 +1274,13 @@ static MemorySegment ofArray(long[] longArray) {
12751274
* @return a heap memory segment backed by a double array.
12761275
*/
12771276
static MemorySegment ofArray(double[] doubleArray) {
1278-
return HeapMemorySegmentImpl.OfDouble.fromArray(doubleArray);
1277+
return SegmentFactories.fromArray(doubleArray);
12791278
}
12801279

12811280
/**
1282-
* A zero-length native segment modelling the {@code NULL} address.
1281+
* A zero-length native segment modelling the {@code NULL} address. Equivalent to {@code MemorySegment.ofAddress(0L)}.
12831282
*/
1284-
MemorySegment NULL = new NativeMemorySegmentImpl();
1283+
MemorySegment NULL = MemorySegment.ofAddress(0L);
12851284

12861285
/**
12871286
* Creates a zero-length native segment from the given {@linkplain #address() address value}.
@@ -1295,7 +1294,7 @@ static MemorySegment ofArray(double[] doubleArray) {
12951294
* @return a zero-length native segment with the given address.
12961295
*/
12971296
static MemorySegment ofAddress(long address) {
1298-
return NativeMemorySegmentImpl.makeNativeSegmentUnchecked(address, 0);
1297+
return SegmentFactories.makeNativeSegmentUnchecked(address, 0);
12991298
}
13001299

13011300
/**

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,9 @@ public MemorySegment reinterpretInternal(Class<?> callerClass, long newSize, Sco
151151
}
152152
if (!isNative()) throw new UnsupportedOperationException("Not a native segment");
153153
Runnable action = cleanup != null ?
154-
() -> cleanup.accept(NativeMemorySegmentImpl.makeNativeSegmentUnchecked(address(), newSize)) :
154+
() -> cleanup.accept(SegmentFactories.makeNativeSegmentUnchecked(address(), newSize)) :
155155
null;
156-
return NativeMemorySegmentImpl.makeNativeSegmentUnchecked(address(), newSize,
156+
return SegmentFactories.makeNativeSegmentUnchecked(address(), newSize,
157157
(MemorySessionImpl)scope, action);
158158
}
159159

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public void close() {
5252

5353
public MemorySegment allocateNoInit(long byteSize, long byteAlignment) {
5454
Utils.checkAllocationSizeAndAlign(byteSize, byteAlignment);
55-
return NativeMemorySegmentImpl.makeNativeSegmentNoZeroing(byteSize, byteAlignment, session, shouldReserveMemory);
55+
return SegmentFactories.allocateSegment(byteSize, byteAlignment, session, shouldReserveMemory);
5656
}
5757

5858
@Override

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

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626

2727
package jdk.internal.foreign;
2828

29-
import java.lang.foreign.MemorySegment;
3029
import java.lang.foreign.ValueLayout;
3130
import java.nio.ByteBuffer;
3231
import java.util.Objects;
@@ -48,7 +47,7 @@
4847
* using sharper types would require use of type-conversions, which in turn would inhibit some C2 optimizations,
4948
* such as the elimination of store barriers in methods like {@link HeapMemorySegmentImpl#dup(long, long, boolean, MemorySessionImpl)}.
5049
*/
51-
public abstract sealed class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl {
50+
abstract sealed class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl {
5251

5352
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
5453
private static final int BYTE_ARR_BASE = UNSAFE.arrayBaseOffset(byte[].class);
@@ -110,13 +109,6 @@ public byte[] unsafeGetBase() {
110109
return (byte[])Objects.requireNonNull(base);
111110
}
112111

113-
public static MemorySegment fromArray(byte[] arr) {
114-
Objects.requireNonNull(arr);
115-
long byteSize = (long)arr.length * Unsafe.ARRAY_BYTE_INDEX_SCALE;
116-
return new OfByte(Unsafe.ARRAY_BYTE_BASE_OFFSET, arr, byteSize, false,
117-
MemorySessionImpl.heapSession(arr));
118-
}
119-
120112
@Override
121113
public long maxAlignMask() {
122114
return MAX_ALIGN_1;
@@ -144,13 +136,6 @@ public char[] unsafeGetBase() {
144136
return (char[])Objects.requireNonNull(base);
145137
}
146138

147-
public static MemorySegment fromArray(char[] arr) {
148-
Objects.requireNonNull(arr);
149-
long byteSize = (long)arr.length * Unsafe.ARRAY_CHAR_INDEX_SCALE;
150-
return new OfChar(Unsafe.ARRAY_CHAR_BASE_OFFSET, arr, byteSize, false,
151-
MemorySessionImpl.heapSession(arr));
152-
}
153-
154139
@Override
155140
public long maxAlignMask() {
156141
return MAX_ALIGN_2;
@@ -178,13 +163,6 @@ public short[] unsafeGetBase() {
178163
return (short[])Objects.requireNonNull(base);
179164
}
180165

181-
public static MemorySegment fromArray(short[] arr) {
182-
Objects.requireNonNull(arr);
183-
long byteSize = (long)arr.length * Unsafe.ARRAY_SHORT_INDEX_SCALE;
184-
return new OfShort(Unsafe.ARRAY_SHORT_BASE_OFFSET, arr, byteSize, false,
185-
MemorySessionImpl.heapSession(arr));
186-
}
187-
188166
@Override
189167
public long maxAlignMask() {
190168
return MAX_ALIGN_2;
@@ -212,13 +190,6 @@ public int[] unsafeGetBase() {
212190
return (int[])Objects.requireNonNull(base);
213191
}
214192

215-
public static MemorySegment fromArray(int[] arr) {
216-
Objects.requireNonNull(arr);
217-
long byteSize = (long)arr.length * Unsafe.ARRAY_INT_INDEX_SCALE;
218-
return new OfInt(Unsafe.ARRAY_INT_BASE_OFFSET, arr, byteSize, false,
219-
MemorySessionImpl.heapSession(arr));
220-
}
221-
222193
@Override
223194
public long maxAlignMask() {
224195
return MAX_ALIGN_4;
@@ -246,13 +217,6 @@ public long[] unsafeGetBase() {
246217
return (long[])Objects.requireNonNull(base);
247218
}
248219

249-
public static MemorySegment fromArray(long[] arr) {
250-
Objects.requireNonNull(arr);
251-
long byteSize = (long)arr.length * Unsafe.ARRAY_LONG_INDEX_SCALE;
252-
return new OfLong(Unsafe.ARRAY_LONG_BASE_OFFSET, arr, byteSize, false,
253-
MemorySessionImpl.heapSession(arr));
254-
}
255-
256220
@Override
257221
public long maxAlignMask() {
258222
return MAX_ALIGN_8;
@@ -280,13 +244,6 @@ public float[] unsafeGetBase() {
280244
return (float[])Objects.requireNonNull(base);
281245
}
282246

283-
public static MemorySegment fromArray(float[] arr) {
284-
Objects.requireNonNull(arr);
285-
long byteSize = (long)arr.length * Unsafe.ARRAY_FLOAT_INDEX_SCALE;
286-
return new OfFloat(Unsafe.ARRAY_FLOAT_BASE_OFFSET, arr, byteSize, false,
287-
MemorySessionImpl.heapSession(arr));
288-
}
289-
290247
@Override
291248
public long maxAlignMask() {
292249
return MAX_ALIGN_4;
@@ -314,13 +271,6 @@ public double[] unsafeGetBase() {
314271
return (double[])Objects.requireNonNull(base);
315272
}
316273

317-
public static MemorySegment fromArray(double[] arr) {
318-
Objects.requireNonNull(arr);
319-
long byteSize = (long)arr.length * Unsafe.ARRAY_DOUBLE_INDEX_SCALE;
320-
return new OfDouble(Unsafe.ARRAY_DOUBLE_BASE_OFFSET, arr, byteSize, false,
321-
MemorySessionImpl.heapSession(arr));
322-
}
323-
324274
@Override
325275
public long maxAlignMask() {
326276
return MAX_ALIGN_8;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
* memory mapped segment, such as the file descriptor associated with the mapping. This information is crucial
3636
* in order to correctly reconstruct a byte buffer object from the segment (see {@link #makeByteBuffer()}).
3737
*/
38-
public final class MappedMemorySegmentImpl extends NativeMemorySegmentImpl {
38+
final class MappedMemorySegmentImpl extends NativeMemorySegmentImpl {
3939

4040
private final UnmapperProxy unmapper;
4141

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

Lines changed: 1 addition & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,13 @@
3131
import java.util.Optional;
3232

3333
import jdk.internal.misc.Unsafe;
34-
import jdk.internal.misc.VM;
3534
import jdk.internal.vm.annotation.ForceInline;
3635

3736
/**
3837
* Implementation for native memory segments. A native memory segment is essentially a wrapper around
3938
* a native long address.
4039
*/
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;
40+
sealed class NativeMemorySegmentImpl extends AbstractMemorySegmentImpl permits MappedMemorySegmentImpl {
4841

4942
final long min;
5043

@@ -58,17 +51,6 @@ public sealed class NativeMemorySegmentImpl extends AbstractMemorySegmentImpl pe
5851
: min;
5952
}
6053

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() {
68-
super(0L, false, new GlobalSession(null));
69-
this.min = 0L;
70-
}
71-
7254
@Override
7355
public long address() {
7456
return min;
@@ -110,72 +92,4 @@ public Object unsafeGetBase() {
11092
public long maxAlignMask() {
11193
return 0;
11294
}
113-
114-
// factories
115-
116-
public static MemorySegment makeNativeSegmentNoZeroing(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
178-
public static MemorySegment makeNativeSegmentUnchecked(long min, long byteSize) {
179-
return new NativeMemorySegmentImpl(min, byteSize, false, new GlobalSession(null));
180-
}
18195
}

0 commit comments

Comments
 (0)