Skip to content

Commit 5967aaf

Browse files
plevartmcimadamore
authored andcommittedMay 29, 2020
8246050: Improve scalability of MemoryScope
Reiplement memory scope using StampedLock Reviewed-by: psandoz
1 parent 4708c6d commit 5967aaf

File tree

6 files changed

+291
-111
lines changed

6 files changed

+291
-111
lines changed
 

‎src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java

+23-29
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
package jdk.internal.foreign;
2727

2828
import jdk.incubator.foreign.MemoryAddress;
29+
import jdk.incubator.foreign.MemoryLayout;
30+
import jdk.incubator.foreign.MemoryLayouts;
2931
import jdk.incubator.foreign.MemorySegment;
3032
import jdk.incubator.foreign.SequenceLayout;
3133
import jdk.internal.access.JavaNioAccess;
@@ -68,22 +70,20 @@ public abstract class AbstractMemorySegmentImpl implements MemorySegment, Memory
6870

6971
final long length;
7072
final int mask;
71-
final Thread owner;
7273
final MemoryScope scope;
7374

7475
@ForceInline
75-
AbstractMemorySegmentImpl(long length, int mask, Thread owner, MemoryScope scope) {
76+
AbstractMemorySegmentImpl(long length, int mask, MemoryScope scope) {
7677
this.length = length;
7778
this.mask = mask;
78-
this.owner = owner;
7979
this.scope = scope;
8080
}
8181

8282
abstract long min();
8383

8484
abstract Object base();
8585

86-
abstract AbstractMemorySegmentImpl dup(long offset, long size, int mask, Thread owner, MemoryScope scope);
86+
abstract AbstractMemorySegmentImpl dup(long offset, long size, int mask, MemoryScope scope);
8787

8888
abstract ByteBuffer makeByteBuffer();
8989

@@ -100,7 +100,7 @@ public AbstractMemorySegmentImpl asSlice(long offset, long newSize) {
100100
}
101101

102102
private AbstractMemorySegmentImpl asSliceNoCheck(long offset, long newSize) {
103-
return dup(offset, newSize, mask, owner, scope);
103+
return dup(offset, newSize, mask, scope);
104104
}
105105

106106
@SuppressWarnings("unchecked")
@@ -145,12 +145,12 @@ public final long byteSize() {
145145

146146
@Override
147147
public final boolean isAlive() {
148-
return scope.isAliveThreadSafe();
148+
return scope.isAlive();
149149
}
150150

151151
@Override
152152
public Thread ownerThread() {
153-
return owner;
153+
return scope.ownerThread();
154154
}
155155

156156
@Override
@@ -159,7 +159,7 @@ public AbstractMemorySegmentImpl withAccessModes(int accessModes) {
159159
if ((~accessModes() & accessModes) != 0) {
160160
throw new IllegalArgumentException("Cannot acquire more access modes");
161161
}
162-
return dup(0, length, (mask & ~ACCESS_MASK) | accessModes, owner, scope);
162+
return dup(0, length, (mask & ~ACCESS_MASK) | accessModes, scope);
163163
}
164164

165165
@Override
@@ -177,17 +177,16 @@ private void checkAccessModes(int accessModes) {
177177
@Override
178178
public MemorySegment withOwnerThread(Thread newOwner) {
179179
Objects.requireNonNull(newOwner);
180-
checkValidState();
181180
if (!isSet(HANDOFF)) {
182181
throw unsupportedAccessMode(HANDOFF);
183182
}
184-
if (owner == newOwner) {
183+
if (scope.ownerThread() == newOwner) {
185184
throw new IllegalArgumentException("Segment already owned by thread: " + newOwner);
186185
} else {
187186
try {
188-
return dup(0L, length, mask, newOwner, scope.dup());
187+
return dup(0L, length, mask, scope.dup(newOwner));
189188
} finally {
190-
//flush read/writes to memory before returning the new segment
189+
//flush read/writes to segment memory before returning the new segment
191190
VarHandle.fullFence();
192191
}
193192
}
@@ -198,19 +197,18 @@ public final void close() {
198197
if (!isSet(CLOSE)) {
199198
throw unsupportedAccessMode(CLOSE);
200199
}
201-
checkValidState();
202200
closeNoCheck();
203201
}
204202

205203
private final void closeNoCheck() {
206-
scope.close(true);
204+
scope.close();
207205
}
208206

209207
final AbstractMemorySegmentImpl acquire() {
210208
if (Thread.currentThread() != ownerThread() && !isSet(ACQUIRE)) {
211209
throw unsupportedAccessMode(ACQUIRE);
212210
}
213-
return dup(0, length, mask, Thread.currentThread(), scope.acquire());
211+
return dup(0, length, mask, scope.acquire());
214212
}
215213

216214
@Override
@@ -227,7 +225,7 @@ boolean isSmall() {
227225
}
228226

229227
void checkRange(long offset, long length, boolean writeAccess) {
230-
checkValidState();
228+
scope.checkValidState();
231229
if (writeAccess && !isSet(WRITE)) {
232230
throw unsupportedAccessMode(WRITE);
233231
} else if (!writeAccess && !isSet(READ)) {
@@ -238,10 +236,7 @@ void checkRange(long offset, long length, boolean writeAccess) {
238236

239237
@Override
240238
public final void checkValidState() {
241-
if (owner != null && owner != Thread.currentThread()) {
242-
throw new IllegalStateException("Attempt to access segment outside owning thread");
243-
}
244-
scope.checkAliveConfined();
239+
scope.checkValidState();
245240
}
246241

247242
// Helper methods
@@ -415,29 +410,28 @@ public static AbstractMemorySegmentImpl ofBuffer(ByteBuffer bb) {
415410
AbstractMemorySegmentImpl bufferSegment = (AbstractMemorySegmentImpl)nioAccess.bufferSegment(bb);
416411
final MemoryScope bufferScope;
417412
int modes;
418-
final Thread owner;
419413
if (bufferSegment != null) {
420414
bufferScope = bufferSegment.scope;
421415
modes = bufferSegment.mask;
422-
owner = bufferSegment.owner;
423416
} else {
424-
bufferScope = new MemoryScope(bb, null);
417+
bufferScope = MemoryScope.create(bb, null);
425418
modes = defaultAccessModes(size);
426-
owner = Thread.currentThread();
427419
}
428420
if (bb.isReadOnly()) {
429421
modes &= ~WRITE;
430422
}
431423
if (base != null) {
432-
return new HeapMemorySegmentImpl<>(bbAddress + pos, () -> (byte[])base, size, modes, owner, bufferScope);
424+
return new HeapMemorySegmentImpl<>(bbAddress + pos, () -> (byte[])base, size, modes, bufferScope);
433425
} else if (unmapper == null) {
434-
return new NativeMemorySegmentImpl(bbAddress + pos, size, modes, owner, bufferScope);
426+
return new NativeMemorySegmentImpl(bbAddress + pos, size, modes, bufferScope);
435427
} else {
436-
return new MappedMemorySegmentImpl(bbAddress + pos, unmapper, size, modes, owner, bufferScope);
428+
return new MappedMemorySegmentImpl(bbAddress + pos, unmapper, size, modes, bufferScope);
437429
}
438430
}
439431

440-
public static AbstractMemorySegmentImpl NOTHING = new AbstractMemorySegmentImpl(0, 0, null, MemoryScope.GLOBAL) {
432+
public static final AbstractMemorySegmentImpl NOTHING = new AbstractMemorySegmentImpl(
433+
0, 0, MemoryScope.createUnchecked(null, null, null)
434+
) {
441435
@Override
442436
ByteBuffer makeByteBuffer() {
443437
throw new UnsupportedOperationException();
@@ -454,7 +448,7 @@ Object base() {
454448
}
455449

456450
@Override
457-
AbstractMemorySegmentImpl dup(long offset, long size, int mask, Thread owner, MemoryScope scope) {
451+
AbstractMemorySegmentImpl dup(long offset, long size, int mask, MemoryScope scope) {
458452
throw new UnsupportedOperationException();
459453
}
460454
};

‎src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/HeapMemorySegmentImpl.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ public class HeapMemorySegmentImpl<H> extends AbstractMemorySegmentImpl {
5252
final Supplier<H> baseProvider;
5353

5454
@ForceInline
55-
HeapMemorySegmentImpl(long offset, Supplier<H> baseProvider, long length, int mask, Thread owner, MemoryScope scope) {
56-
super(length, mask, owner, scope);
55+
HeapMemorySegmentImpl(long offset, Supplier<H> baseProvider, long length, int mask, MemoryScope scope) {
56+
super(length, mask, scope);
5757
this.offset = offset;
5858
this.baseProvider = baseProvider;
5959
}
@@ -69,8 +69,8 @@ long min() {
6969
}
7070

7171
@Override
72-
HeapMemorySegmentImpl<H> dup(long offset, long size, int mask, Thread owner, MemoryScope scope) {
73-
return new HeapMemorySegmentImpl<H>(this.offset + offset, baseProvider, size, mask, owner, scope);
72+
HeapMemorySegmentImpl<H> dup(long offset, long size, int mask, MemoryScope scope) {
73+
return new HeapMemorySegmentImpl<>(this.offset + offset, baseProvider, size, mask, scope);
7474
}
7575

7676
@Override
@@ -121,7 +121,7 @@ public static MemorySegment makeArraySegment(double[] arr) {
121121

122122
static <Z> HeapMemorySegmentImpl<Z> makeHeapSegment(Supplier<Z> obj, int length, int base, int scale) {
123123
int byteSize = length * scale;
124-
MemoryScope scope = new MemoryScope(null, null);
125-
return new HeapMemorySegmentImpl<>(base, obj, byteSize, defaultAccessModes(byteSize), Thread.currentThread(), scope);
124+
MemoryScope scope = MemoryScope.create(null, null);
125+
return new HeapMemorySegmentImpl<>(base, obj, byteSize, defaultAccessModes(byteSize), scope);
126126
}
127127
}

‎src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/MappedMemorySegmentImpl.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ public class MappedMemorySegmentImpl extends NativeMemorySegmentImpl implements
4848

4949
private final UnmapperProxy unmapper;
5050

51-
MappedMemorySegmentImpl(long min, UnmapperProxy unmapper, long length, int mask, Thread owner, MemoryScope scope) {
52-
super(min, length, mask, owner, scope);
51+
MappedMemorySegmentImpl(long min, UnmapperProxy unmapper, long length, int mask, MemoryScope scope) {
52+
super(min, length, mask, scope);
5353
this.unmapper = unmapper;
5454
}
5555

@@ -60,8 +60,8 @@ ByteBuffer makeByteBuffer() {
6060
}
6161

6262
@Override
63-
MappedMemorySegmentImpl dup(long offset, long size, int mask, Thread owner, MemoryScope scope) {
64-
return new MappedMemorySegmentImpl(min + offset, unmapper, size, mask, owner, scope);
63+
MappedMemorySegmentImpl dup(long offset, long size, int mask, MemoryScope scope) {
64+
return new MappedMemorySegmentImpl(min + offset, unmapper, size, mask, scope);
6565
}
6666

6767
// mapped segment methods
@@ -103,13 +103,13 @@ public static MappedMemorySegment makeMappedSegment(Path path, long bytesSize, F
103103
if (bytesSize <= 0) throw new IllegalArgumentException("Requested bytes size must be > 0.");
104104
try (FileChannelImpl channelImpl = (FileChannelImpl)FileChannel.open(path, openOptions(mapMode))) {
105105
UnmapperProxy unmapperProxy = channelImpl.mapInternal(mapMode, 0L, bytesSize);
106-
MemoryScope scope = new MemoryScope(null, unmapperProxy::unmap);
106+
MemoryScope scope = MemoryScope.create(null, unmapperProxy::unmap);
107107
int modes = defaultAccessModes(bytesSize);
108108
if (mapMode == FileChannel.MapMode.READ_ONLY) {
109109
modes &= ~WRITE;
110110
}
111111
return new MappedMemorySegmentImpl(unmapperProxy.address(), unmapperProxy, bytesSize,
112-
modes, Thread.currentThread(), scope);
112+
modes, scope);
113113
}
114114
}
115115

0 commit comments

Comments
 (0)
Please sign in to comment.