diff --git a/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java b/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java index 6c9cf51bee8b7..698185a108fdc 100644 --- a/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java +++ b/src/java.base/share/classes/java/lang/foreign/SegmentAllocator.java @@ -140,12 +140,12 @@ default MemorySegment allocateFrom(String str, Charset charset) { int length; if (StringSupport.bytesCompatible(str, charset)) { length = str.length(); - segment = allocateNoInit((long) length + termCharSize); + segment = asUninitialized().allocate((long) length + termCharSize); StringSupport.copyToSegmentRaw(str, segment, 0); } else { byte[] bytes = str.getBytes(charset); length = bytes.length; - segment = allocateNoInit((long) bytes.length + termCharSize); + segment = asUninitialized().allocate((long) bytes.length + termCharSize); MemorySegment.copy(bytes, 0, segment, ValueLayout.JAVA_BYTE, 0, bytes.length); } for (int i = 0 ; i < termCharSize ; i++) { @@ -174,7 +174,7 @@ default MemorySegment allocateFrom(String str, Charset charset) { */ default MemorySegment allocateFrom(ValueLayout.OfByte layout, byte value) { Objects.requireNonNull(layout); - MemorySegment seg = allocateNoInit(layout); + MemorySegment seg = asUninitialized().allocate(layout); seg.set(layout, 0, value); return seg; } @@ -199,7 +199,7 @@ default MemorySegment allocateFrom(ValueLayout.OfByte layout, byte value) { */ default MemorySegment allocateFrom(ValueLayout.OfChar layout, char value) { Objects.requireNonNull(layout); - MemorySegment seg = allocateNoInit(layout); + MemorySegment seg = asUninitialized().allocate(layout); seg.set(layout, 0, value); return seg; } @@ -224,7 +224,7 @@ default MemorySegment allocateFrom(ValueLayout.OfChar layout, char value) { */ default MemorySegment allocateFrom(ValueLayout.OfShort layout, short value) { Objects.requireNonNull(layout); - MemorySegment seg = allocateNoInit(layout); + MemorySegment seg = asUninitialized().allocate(layout); seg.set(layout, 0, value); return seg; } @@ -249,7 +249,7 @@ default MemorySegment allocateFrom(ValueLayout.OfShort layout, short value) { */ default MemorySegment allocateFrom(ValueLayout.OfInt layout, int value) { Objects.requireNonNull(layout); - MemorySegment seg = allocateNoInit(layout); + MemorySegment seg = asUninitialized().allocate(layout); seg.set(layout, 0, value); return seg; } @@ -274,7 +274,7 @@ default MemorySegment allocateFrom(ValueLayout.OfInt layout, int value) { */ default MemorySegment allocateFrom(ValueLayout.OfFloat layout, float value) { Objects.requireNonNull(layout); - MemorySegment seg = allocateNoInit(layout); + MemorySegment seg = asUninitialized().allocate(layout); seg.set(layout, 0, value); return seg; } @@ -299,7 +299,7 @@ default MemorySegment allocateFrom(ValueLayout.OfFloat layout, float value) { */ default MemorySegment allocateFrom(ValueLayout.OfLong layout, long value) { Objects.requireNonNull(layout); - MemorySegment seg = allocateNoInit(layout); + MemorySegment seg = asUninitialized().allocate(layout); seg.set(layout, 0, value); return seg; } @@ -324,7 +324,7 @@ default MemorySegment allocateFrom(ValueLayout.OfLong layout, long value) { */ default MemorySegment allocateFrom(ValueLayout.OfDouble layout, double value) { Objects.requireNonNull(layout); - MemorySegment seg = allocateNoInit(layout); + MemorySegment seg = asUninitialized().allocate(layout); seg.set(layout, 0, value); return seg; } @@ -357,7 +357,7 @@ default MemorySegment allocateFrom(ValueLayout.OfDouble layout, double value) { default MemorySegment allocateFrom(AddressLayout layout, MemorySegment value) { Objects.requireNonNull(value); Objects.requireNonNull(layout); - MemorySegment segment = allocateNoInit(layout); + MemorySegment segment = asUninitialized().allocate(layout); segment.set(layout, 0, value); return segment; } @@ -405,7 +405,7 @@ default MemorySegment allocateFrom(ValueLayout elementLayout, Objects.requireNonNull(source); Objects.requireNonNull(sourceElementLayout); Objects.requireNonNull(elementLayout); - MemorySegment dest = allocateNoInit(elementLayout, elementCount); + MemorySegment dest = asUninitialized().allocate(elementLayout, elementCount); MemorySegment.copy(source, sourceElementLayout, sourceOffset, dest, elementLayout, 0, elementCount); return dest; } @@ -659,6 +659,13 @@ default MemorySegment allocate(long byteSize) { */ MemorySegment allocate(long byteSize, long byteAlignment); + /** + * {@return a view of this allocator which does not initialize freshly allocated memory} + * Not all allocators support this. When not supported, an allocator is allowed + * to return itself. + */ + default SegmentAllocator asUninitialized() { return this; } + /** * Returns a segment allocator that responds to allocation requests by returning * consecutive slices obtained from the provided segment. Each new allocation @@ -718,25 +725,4 @@ private static void assertWritable(MemorySegment segment) { throw new IllegalArgumentException("read-only segment"); } } - - @ForceInline - private MemorySegment allocateNoInit(long byteSize) { - return this instanceof ArenaImpl arenaImpl ? - arenaImpl.allocateNoInit(byteSize, 1) : - allocate(byteSize); - } - - @ForceInline - private MemorySegment allocateNoInit(MemoryLayout layout) { - return this instanceof ArenaImpl arenaImpl ? - arenaImpl.allocateNoInit(layout.byteSize(), layout.byteAlignment()) : - allocate(layout); - } - - @ForceInline - private MemorySegment allocateNoInit(MemoryLayout layout, long size) { - return this instanceof ArenaImpl arenaImpl ? - arenaImpl.allocateNoInit(layout.byteSize() * size, layout.byteAlignment()) : - allocate(layout, size); - } } diff --git a/src/java.base/share/classes/jdk/internal/foreign/ArenaImpl.java b/src/java.base/share/classes/jdk/internal/foreign/ArenaImpl.java index 027aed5f8cc01..232004984bb53 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/ArenaImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/ArenaImpl.java @@ -25,19 +25,16 @@ package jdk.internal.foreign; -import java.lang.foreign.Arena; -import java.lang.foreign.MemoryLayout; -import java.lang.foreign.MemorySegment; +import java.lang.foreign.*; import java.lang.foreign.MemorySegment.Scope; +import java.nio.charset.Charset; import java.util.Objects; public final class ArenaImpl implements Arena { private final MemorySessionImpl session; - private final boolean shouldReserveMemory; ArenaImpl(MemorySessionImpl session) { this.session = session; - shouldReserveMemory = session instanceof ImplicitSession; } @Override @@ -50,14 +47,99 @@ public void close() { session.close(); } - public MemorySegment allocateNoInit(long byteSize, long byteAlignment) { - Utils.checkAllocationSizeAndAlign(byteSize, byteAlignment); - return SegmentFactories.allocateSegment(byteSize, byteAlignment, session, shouldReserveMemory); + @Override + public MemorySegment allocate(long byteSize, long byteAlignment) { + return session.allocate(byteSize, byteAlignment) + .fill((byte)0); } @Override - public MemorySegment allocate(long byteSize, long byteAlignment) { - MemorySegment segment = allocateNoInit(byteSize, byteAlignment); - return segment.fill((byte)0); + public MemorySegment allocateFrom(String str) { + return session.allocateFrom(str); + } + + @Override + public MemorySegment allocateFrom(String str, Charset charset) { + return session.allocateFrom(str, charset); + } + + @Override + public MemorySegment allocateFrom(ValueLayout.OfByte layout, byte value) { + return session.allocateFrom(layout, value); + } + + @Override + public MemorySegment allocateFrom(ValueLayout.OfChar layout, char value) { + return session.allocateFrom(layout, value); + } + + @Override + public MemorySegment allocateFrom(ValueLayout.OfShort layout, short value) { + return session.allocateFrom(layout, value); + } + + @Override + public MemorySegment allocateFrom(ValueLayout.OfInt layout, int value) { + return session.allocateFrom(layout, value); + } + + @Override + public MemorySegment allocateFrom(ValueLayout.OfFloat layout, float value) { + return session.allocateFrom(layout, value); + } + + @Override + public MemorySegment allocateFrom(ValueLayout.OfLong layout, long value) { + return session.allocateFrom(layout, value); + } + + @Override + public MemorySegment allocateFrom(ValueLayout.OfDouble layout, double value) { + return session.allocateFrom(layout, value); + } + + @Override + public MemorySegment allocateFrom(AddressLayout layout, MemorySegment value) { + return session.allocateFrom(layout, value); + } + + @Override + public MemorySegment allocateFrom(ValueLayout elementLayout, MemorySegment source, ValueLayout sourceElementLayout, long sourceOffset, long elementCount) { + return session.allocateFrom(elementLayout, source, sourceElementLayout, sourceOffset, elementCount); + } + + @Override + public MemorySegment allocateFrom(ValueLayout.OfByte elementLayout, byte... elements) { + return session.allocateFrom(elementLayout, elements); + } + + @Override + public MemorySegment allocateFrom(ValueLayout.OfShort elementLayout, short... elements) { + return session.allocateFrom(elementLayout, elements); + } + + @Override + public MemorySegment allocateFrom(ValueLayout.OfChar elementLayout, char... elements) { + return session.allocateFrom(elementLayout, elements); + } + + @Override + public MemorySegment allocateFrom(ValueLayout.OfInt elementLayout, int... elements) { + return session.allocateFrom(elementLayout, elements); + } + + @Override + public MemorySegment allocateFrom(ValueLayout.OfFloat elementLayout, float... elements) { + return session.allocateFrom(elementLayout, elements); + } + + @Override + public MemorySegment allocateFrom(ValueLayout.OfLong elementLayout, long... elements) { + return session.allocateFrom(elementLayout, elements); + } + + @Override + public MemorySegment allocateFrom(ValueLayout.OfDouble elementLayout, double... elements) { + return session.allocateFrom(elementLayout, elements); } } diff --git a/src/java.base/share/classes/jdk/internal/foreign/ImplicitSession.java b/src/java.base/share/classes/jdk/internal/foreign/ImplicitSession.java index 0eb3642508c09..ac80d87fe595b 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/ImplicitSession.java +++ b/src/java.base/share/classes/jdk/internal/foreign/ImplicitSession.java @@ -64,4 +64,9 @@ public boolean isCloseable() { public void justClose() { throw nonCloseable(); } + + @Override + public boolean shouldReserve() { + return true; + } } diff --git a/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java b/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java index a12b16ca8b4fa..b3dcfb48c2921 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java @@ -29,6 +29,7 @@ import java.lang.foreign.MemorySegment; import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment.Scope; +import java.lang.foreign.SegmentAllocator; import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; import java.lang.ref.Cleaner; @@ -53,7 +54,7 @@ * access is possible when a session is being closed (see {@link jdk.internal.misc.ScopedMemoryAccess}). */ public abstract sealed class MemorySessionImpl - implements Scope + implements Scope, SegmentAllocator permits ConfinedSession, GlobalSession, SharedSession { static final int OPEN = 0; static final int CLOSED = -1; @@ -218,6 +219,17 @@ public boolean isCloseable() { return true; } + @Override + public MemorySegment allocate(long byteSize, long byteAlignment) { + Utils.checkAllocationSizeAndAlign(byteSize, byteAlignment); + boolean shouldReserve = shouldReserve(); + return SegmentFactories.allocateSegment(byteSize, byteAlignment, this, shouldReserve); + } + + public boolean shouldReserve() { + return false; + } + /** * Closes this session, executing any cleanup action (where provided). * @throws IllegalStateException if this session is already closed or if this is