8318324: Drop redundant default methods from FFM API
Reviewed-by: jvernee
This commit is contained in:
parent
1a098356dd
commit
15acf4b8d7
src/java.base/share/classes
java/lang/foreign
jdk/internal/foreign
@ -26,14 +26,9 @@
|
||||
package java.lang.foreign;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.internal.foreign.LayoutPath;
|
||||
@ -44,7 +39,6 @@ import jdk.internal.foreign.layout.PaddingLayoutImpl;
|
||||
import jdk.internal.foreign.layout.SequenceLayoutImpl;
|
||||
import jdk.internal.foreign.layout.StructLayoutImpl;
|
||||
import jdk.internal.foreign.layout.UnionLayoutImpl;
|
||||
import jdk.internal.vm.annotation.ForceInline;
|
||||
|
||||
/**
|
||||
* A memory layout describes the contents of a memory segment.
|
||||
@ -404,35 +398,12 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin
|
||||
* @throws IllegalArgumentException if {@code offset} or {@code index} is negative
|
||||
* @throws ArithmeticException if either the addition or multiplication overflows
|
||||
*/
|
||||
@ForceInline
|
||||
default long scale(long offset, long index) {
|
||||
if (offset < 0) {
|
||||
throw new IllegalArgumentException("Negative offset: " + offset);
|
||||
}
|
||||
if (index < 0) {
|
||||
throw new IllegalArgumentException("Negative index: " + index);
|
||||
}
|
||||
|
||||
return Math.addExact(offset, Math.multiplyExact(byteSize(), index));
|
||||
}
|
||||
long scale(long offset, long index);
|
||||
|
||||
/**
|
||||
*{@return a method handle that can be used to invoke {@link #scale(long, long)} on this layout}
|
||||
*/
|
||||
default MethodHandle scaleHandle() {
|
||||
class Holder {
|
||||
static final MethodHandle MH_SCALE;
|
||||
static {
|
||||
try {
|
||||
MH_SCALE = MethodHandles.lookup().findVirtual(MemoryLayout.class, "scale",
|
||||
MethodType.methodType(long.class, long.class, long.class));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Holder.MH_SCALE.bindTo(this);
|
||||
}
|
||||
MethodHandle scaleHandle();
|
||||
|
||||
/**
|
||||
* Computes the offset, in bytes, of the layout selected by the given layout path, where the initial layout in the
|
||||
@ -444,10 +415,7 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin
|
||||
* @throws IllegalArgumentException if the layout path contains one or more <a href=#open-path-elements>open path elements</a>.
|
||||
* @throws IllegalArgumentException if the layout path contains one or more <a href=#deref-path-elements>dereference path elements</a>.
|
||||
*/
|
||||
default long byteOffset(PathElement... elements) {
|
||||
return computePathOp(LayoutPath.rootPath(this), LayoutPath::offset,
|
||||
EnumSet.of(PathKind.SEQUENCE_ELEMENT, PathKind.SEQUENCE_RANGE, PathKind.DEREF_ELEMENT), elements);
|
||||
}
|
||||
long byteOffset(PathElement... elements);
|
||||
|
||||
/**
|
||||
* Creates a method handle that computes the offset, in bytes, of the layout selected
|
||||
@ -482,10 +450,7 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin
|
||||
* @throws IllegalArgumentException if the layout path is not <a href="#well-formedness">well-formed</a> for this layout.
|
||||
* @throws IllegalArgumentException if the layout path contains one or more <a href=#deref-path-elements>dereference path elements</a>.
|
||||
*/
|
||||
default MethodHandle byteOffsetHandle(PathElement... elements) {
|
||||
return computePathOp(LayoutPath.rootPath(this), LayoutPath::offsetHandle,
|
||||
EnumSet.of(PathKind.DEREF_ELEMENT), elements);
|
||||
}
|
||||
MethodHandle byteOffsetHandle(PathElement... elements);
|
||||
|
||||
/**
|
||||
* Creates a var handle that accesses a memory segment at the offset selected by the given layout path,
|
||||
@ -577,14 +542,7 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin
|
||||
* @throws IllegalArgumentException if the layout path is not <a href="#well-formedness">well-formed</a> for this layout.
|
||||
* @throws IllegalArgumentException if the layout selected by the provided path is not a {@linkplain ValueLayout value layout}.
|
||||
*/
|
||||
default VarHandle varHandle(PathElement... elements) {
|
||||
Objects.requireNonNull(elements);
|
||||
if (this instanceof ValueLayout vl && elements.length == 0) {
|
||||
return vl.varHandle(); // fast path
|
||||
}
|
||||
return computePathOp(LayoutPath.rootPath(this), LayoutPath::dereferenceHandle,
|
||||
Set.of(), elements);
|
||||
}
|
||||
VarHandle varHandle(PathElement... elements);
|
||||
|
||||
/**
|
||||
* Creates a method handle which, given a memory segment, returns a {@linkplain MemorySegment#asSlice(long,long) slice}
|
||||
@ -623,10 +581,7 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin
|
||||
* @throws IllegalArgumentException if the layout path is not <a href="#well-formedness">well-formed</a> for this layout.
|
||||
* @throws IllegalArgumentException if the layout path contains one or more <a href=#deref-path-elements>dereference path elements</a>.
|
||||
*/
|
||||
default MethodHandle sliceHandle(PathElement... elements) {
|
||||
return computePathOp(LayoutPath.rootPath(this), LayoutPath::sliceHandle,
|
||||
Set.of(PathKind.DEREF_ELEMENT), elements);
|
||||
}
|
||||
MethodHandle sliceHandle(PathElement... elements);
|
||||
|
||||
/**
|
||||
* Returns the layout selected from the provided path, where the initial layout in the path is this layout.
|
||||
@ -638,23 +593,7 @@ public sealed interface MemoryLayout permits SequenceLayout, GroupLayout, Paddin
|
||||
* @throws IllegalArgumentException if the layout path contains one or more path elements that select one or more
|
||||
* sequence element indices, such as {@link PathElement#sequenceElement(long)} and {@link PathElement#sequenceElement(long, long)}).
|
||||
*/
|
||||
default MemoryLayout select(PathElement... elements) {
|
||||
return computePathOp(LayoutPath.rootPath(this), LayoutPath::layout,
|
||||
EnumSet.of(PathKind.SEQUENCE_ELEMENT_INDEX, PathKind.SEQUENCE_RANGE, PathKind.DEREF_ELEMENT), elements);
|
||||
}
|
||||
|
||||
private static <Z> Z computePathOp(LayoutPath path, Function<LayoutPath, Z> finalizer,
|
||||
Set<PathKind> badKinds, PathElement... elements) {
|
||||
Objects.requireNonNull(elements);
|
||||
for (PathElement e : elements) {
|
||||
LayoutPath.PathElementImpl pathElem = (LayoutPath.PathElementImpl)Objects.requireNonNull(e);
|
||||
if (badKinds.contains(pathElem.kind())) {
|
||||
throw new IllegalArgumentException(String.format("Invalid %s selection in layout path", pathElem.kind().description()));
|
||||
}
|
||||
path = pathElem.apply(path);
|
||||
}
|
||||
return finalizer.apply(path);
|
||||
}
|
||||
MemoryLayout select(PathElement... elements);
|
||||
|
||||
/**
|
||||
* An element in a <a href="MemoryLayout.html#layout-paths"><em>layout path</em></a>. There
|
||||
|
@ -573,10 +573,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* the alignment constraint specified by {@code layout}.
|
||||
* @return a slice of this memory segment.
|
||||
*/
|
||||
default MemorySegment asSlice(long offset, MemoryLayout layout) {
|
||||
Objects.requireNonNull(layout);
|
||||
return asSlice(offset, layout.byteSize(), layout.byteAlignment());
|
||||
}
|
||||
MemorySegment asSlice(long offset, MemoryLayout layout);
|
||||
|
||||
/**
|
||||
* Returns a slice of this memory segment, at the given offset. The returned segment's address is the address
|
||||
@ -788,10 +785,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
* @return this segment.
|
||||
*/
|
||||
default MemorySegment copyFrom(MemorySegment src) {
|
||||
MemorySegment.copy(src, 0, this, 0, src.byteSize());
|
||||
return this;
|
||||
}
|
||||
MemorySegment copyFrom(MemorySegment src);
|
||||
|
||||
/**
|
||||
* Finds and returns the offset, in bytes, of the first mismatch between
|
||||
@ -820,10 +814,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws WrongThreadException if this method is called from a thread {@code T},
|
||||
* such that {@code other.isAccessibleBy(T) == false}.
|
||||
*/
|
||||
default long mismatch(MemorySegment other) {
|
||||
Objects.requireNonNull(other);
|
||||
return MemorySegment.mismatch(this, 0, byteSize(), other, 0, other.byteSize());
|
||||
}
|
||||
long mismatch(MemorySegment other);
|
||||
|
||||
/**
|
||||
* Determines whether the contents of this mapped segment is resident in physical
|
||||
@ -1068,9 +1059,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws WrongThreadException if this method is called from a thread {@code T},
|
||||
* such that {@code isAccessibleBy(T) == false}.
|
||||
*/
|
||||
default String getString(long offset) {
|
||||
return getString(offset, sun.nio.cs.UTF_8.INSTANCE);
|
||||
}
|
||||
String getString(long offset);
|
||||
|
||||
/**
|
||||
* Reads a null-terminated string from this segment at the given offset, using the provided charset.
|
||||
@ -1099,10 +1088,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* such that {@code isAccessibleBy(T) == false}.
|
||||
* @throws IllegalArgumentException if {@code charset} is not a {@linkplain StandardCharsets standard charset}.
|
||||
*/
|
||||
default String getString(long offset, Charset charset) {
|
||||
Objects.requireNonNull(charset);
|
||||
return StringSupport.read(this, offset, charset);
|
||||
}
|
||||
String getString(long offset, Charset charset);
|
||||
|
||||
/**
|
||||
* Writes the given string into this segment at the given offset, converting it to a null-terminated byte sequence
|
||||
@ -1123,10 +1109,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws WrongThreadException if this method is called from a thread {@code T},
|
||||
* such that {@code isAccessibleBy(T) == false}.
|
||||
*/
|
||||
default void setString(long offset, String str) {
|
||||
Objects.requireNonNull(str);
|
||||
setString(offset, str, sun.nio.cs.UTF_8.INSTANCE);
|
||||
}
|
||||
void setString(long offset, String str);
|
||||
|
||||
/**
|
||||
* Writes the given string into this segment at the given offset, converting it to a null-terminated byte sequence
|
||||
@ -1160,11 +1143,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* such that {@code isAccessibleBy(T) == false}.
|
||||
* @throws IllegalArgumentException if {@code charset} is not a {@linkplain StandardCharsets standard charset}.
|
||||
*/
|
||||
default void setString(long offset, String str, Charset charset) {
|
||||
Objects.requireNonNull(charset);
|
||||
Objects.requireNonNull(str);
|
||||
StringSupport.write(this, offset, charset, str);
|
||||
}
|
||||
void setString(long offset, String str, Charset charset);
|
||||
|
||||
/**
|
||||
* Creates a memory segment that is backed by the same region of memory that backs the given {@link Buffer} instance.
|
||||
@ -1411,10 +1390,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default byte get(ValueLayout.OfByte layout, long offset) {
|
||||
return (byte) layout.varHandle().get(this, offset);
|
||||
}
|
||||
byte get(ValueLayout.OfByte layout, long offset);
|
||||
|
||||
/**
|
||||
* Writes a byte into this segment at the given offset, with the given layout.
|
||||
@ -1431,10 +1407,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void set(ValueLayout.OfByte layout, long offset, byte value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
void set(ValueLayout.OfByte layout, long offset, byte value);
|
||||
|
||||
/**
|
||||
* Reads a boolean from this segment at the given offset, with the given layout.
|
||||
@ -1450,10 +1423,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default boolean get(ValueLayout.OfBoolean layout, long offset) {
|
||||
return (boolean) layout.varHandle().get(this, offset);
|
||||
}
|
||||
boolean get(ValueLayout.OfBoolean layout, long offset);
|
||||
|
||||
/**
|
||||
* Writes a boolean into this segment at the given offset, with the given layout.
|
||||
@ -1470,10 +1440,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void set(ValueLayout.OfBoolean layout, long offset, boolean value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
void set(ValueLayout.OfBoolean layout, long offset, boolean value);
|
||||
|
||||
/**
|
||||
* Reads a char from this segment at the given offset, with the given layout.
|
||||
@ -1489,10 +1456,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default char get(ValueLayout.OfChar layout, long offset) {
|
||||
return (char) layout.varHandle().get(this, offset);
|
||||
}
|
||||
char get(ValueLayout.OfChar layout, long offset);
|
||||
|
||||
/**
|
||||
* Writes a char into this segment at the given offset, with the given layout.
|
||||
@ -1509,10 +1473,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void set(ValueLayout.OfChar layout, long offset, char value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
void set(ValueLayout.OfChar layout, long offset, char value);
|
||||
|
||||
/**
|
||||
* Reads a short from this segment at the given offset, with the given layout.
|
||||
@ -1528,10 +1489,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default short get(ValueLayout.OfShort layout, long offset) {
|
||||
return (short) layout.varHandle().get(this, offset);
|
||||
}
|
||||
short get(ValueLayout.OfShort layout, long offset);
|
||||
|
||||
/**
|
||||
* Writes a short into this segment at the given offset, with the given layout.
|
||||
@ -1548,10 +1506,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void set(ValueLayout.OfShort layout, long offset, short value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
void set(ValueLayout.OfShort layout, long offset, short value);
|
||||
|
||||
/**
|
||||
* Reads an int from this segment at the given offset, with the given layout.
|
||||
@ -1567,10 +1522,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default int get(ValueLayout.OfInt layout, long offset) {
|
||||
return (int) layout.varHandle().get(this, offset);
|
||||
}
|
||||
int get(ValueLayout.OfInt layout, long offset);
|
||||
|
||||
/**
|
||||
* Writes an int into this segment at the given offset, with the given layout.
|
||||
@ -1587,10 +1539,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void set(ValueLayout.OfInt layout, long offset, int value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
void set(ValueLayout.OfInt layout, long offset, int value);
|
||||
|
||||
/**
|
||||
* Reads a float from this segment at the given offset, with the given layout.
|
||||
@ -1606,10 +1555,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default float get(ValueLayout.OfFloat layout, long offset) {
|
||||
return (float)layout.varHandle().get(this, offset);
|
||||
}
|
||||
float get(ValueLayout.OfFloat layout, long offset);
|
||||
|
||||
/**
|
||||
* Writes a float into this segment at the given offset, with the given layout.
|
||||
@ -1626,10 +1572,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void set(ValueLayout.OfFloat layout, long offset, float value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
void set(ValueLayout.OfFloat layout, long offset, float value);
|
||||
|
||||
/**
|
||||
* Reads a long from this segment at the given offset, with the given layout.
|
||||
@ -1645,10 +1588,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default long get(ValueLayout.OfLong layout, long offset) {
|
||||
return (long) layout.varHandle().get(this, offset);
|
||||
}
|
||||
long get(ValueLayout.OfLong layout, long offset);
|
||||
|
||||
/**
|
||||
* Writes a long into this segment at the given offset, with the given layout.
|
||||
@ -1665,10 +1605,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void set(ValueLayout.OfLong layout, long offset, long value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
void set(ValueLayout.OfLong layout, long offset, long value);
|
||||
|
||||
/**
|
||||
* Reads a double from this segment at the given offset, with the given layout.
|
||||
@ -1684,10 +1621,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in the provided layout.
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default double get(ValueLayout.OfDouble layout, long offset) {
|
||||
return (double) layout.varHandle().get(this, offset);
|
||||
}
|
||||
double get(ValueLayout.OfDouble layout, long offset);
|
||||
|
||||
/**
|
||||
* Writes a double into this segment at the given offset, with the given layout.
|
||||
@ -1704,10 +1638,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void set(ValueLayout.OfDouble layout, long offset, double value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
void set(ValueLayout.OfDouble layout, long offset, double value);
|
||||
|
||||
/**
|
||||
* Reads an address from this segment at the given offset, with the given layout. The read address is wrapped in
|
||||
@ -1729,10 +1660,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* <a href="MemorySegment.html#segment-alignment">incompatible with the alignment constraint</a> in {@code T}.
|
||||
* @throws IndexOutOfBoundsException if {@code offset > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default MemorySegment get(AddressLayout layout, long offset) {
|
||||
return (MemorySegment) layout.varHandle().get(this, offset);
|
||||
}
|
||||
MemorySegment get(AddressLayout layout, long offset);
|
||||
|
||||
/**
|
||||
* Writes an address into this segment at the given offset, with the given layout.
|
||||
@ -1750,10 +1678,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
* @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment.
|
||||
*/
|
||||
@ForceInline
|
||||
default void set(AddressLayout layout, long offset, MemorySegment value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
void set(AddressLayout layout, long offset, MemorySegment value);
|
||||
|
||||
/**
|
||||
* Reads a byte from this segment at the given index, scaled by the given layout size.
|
||||
@ -1772,12 +1697,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default byte getAtIndex(ValueLayout.OfByte layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
return (byte) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
byte getAtIndex(ValueLayout.OfByte layout, long index);
|
||||
|
||||
/**
|
||||
* Reads a boolean from this segment at the given index, scaled by the given layout size.
|
||||
@ -1796,12 +1716,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default boolean getAtIndex(ValueLayout.OfBoolean layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
return (boolean) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
boolean getAtIndex(ValueLayout.OfBoolean layout, long index);
|
||||
|
||||
/**
|
||||
* Reads a char from this segment at the given index, scaled by the given layout size.
|
||||
@ -1820,12 +1735,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default char getAtIndex(ValueLayout.OfChar layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
return (char) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
char getAtIndex(ValueLayout.OfChar layout, long index);
|
||||
|
||||
/**
|
||||
* Writes a char into this segment at the given index, scaled by the given layout size.
|
||||
@ -1845,12 +1755,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void setAtIndex(ValueLayout.OfChar layout, long index, char value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
void setAtIndex(ValueLayout.OfChar layout, long index, char value);
|
||||
|
||||
/**
|
||||
* Reads a short from this segment at the given index, scaled by the given layout size.
|
||||
@ -1869,12 +1774,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default short getAtIndex(ValueLayout.OfShort layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
return (short) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
short getAtIndex(ValueLayout.OfShort layout, long index);
|
||||
|
||||
/**
|
||||
* Writes a byte into this segment at the given index, scaled by the given layout size.
|
||||
@ -1894,13 +1794,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void setAtIndex(ValueLayout.OfByte layout, long index, byte value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
|
||||
}
|
||||
void setAtIndex(ValueLayout.OfByte layout, long index, byte value);
|
||||
|
||||
/**
|
||||
* Writes a boolean into this segment at the given index, scaled by the given layout size.
|
||||
@ -1920,12 +1814,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void setAtIndex(ValueLayout.OfBoolean layout, long index, boolean value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
void setAtIndex(ValueLayout.OfBoolean layout, long index, boolean value);
|
||||
|
||||
/**
|
||||
* Writes a short into this segment at the given index, scaled by the given layout size.
|
||||
@ -1945,12 +1834,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void setAtIndex(ValueLayout.OfShort layout, long index, short value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
void setAtIndex(ValueLayout.OfShort layout, long index, short value);
|
||||
|
||||
/**
|
||||
* Reads an int from this segment at the given index, scaled by the given layout size.
|
||||
@ -1969,12 +1853,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default int getAtIndex(ValueLayout.OfInt layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
return (int) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
int getAtIndex(ValueLayout.OfInt layout, long index);
|
||||
|
||||
/**
|
||||
* Writes an int into this segment at the given index, scaled by the given layout size.
|
||||
@ -1994,12 +1873,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void setAtIndex(ValueLayout.OfInt layout, long index, int value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
void setAtIndex(ValueLayout.OfInt layout, long index, int value);
|
||||
|
||||
/**
|
||||
* Reads a float from this segment at the given index, scaled by the given layout size.
|
||||
@ -2018,12 +1892,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default float getAtIndex(ValueLayout.OfFloat layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
return (float) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
float getAtIndex(ValueLayout.OfFloat layout, long index);
|
||||
|
||||
/**
|
||||
* Writes a float into this segment at the given index, scaled by the given layout size.
|
||||
@ -2043,12 +1912,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void setAtIndex(ValueLayout.OfFloat layout, long index, float value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
void setAtIndex(ValueLayout.OfFloat layout, long index, float value);
|
||||
|
||||
/**
|
||||
* Reads a long from this segment at the given index, scaled by the given layout size.
|
||||
@ -2067,12 +1931,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default long getAtIndex(ValueLayout.OfLong layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
return (long) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
long getAtIndex(ValueLayout.OfLong layout, long index);
|
||||
|
||||
/**
|
||||
* Writes a long into this segment at the given index, scaled by the given layout size.
|
||||
@ -2092,12 +1951,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void setAtIndex(ValueLayout.OfLong layout, long index, long value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
void setAtIndex(ValueLayout.OfLong layout, long index, long value);
|
||||
|
||||
/**
|
||||
* Reads a double from this segment at the given index, scaled by the given layout size.
|
||||
@ -2116,12 +1970,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default double getAtIndex(ValueLayout.OfDouble layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
return (double) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
double getAtIndex(ValueLayout.OfDouble layout, long index);
|
||||
|
||||
/**
|
||||
* Writes a double into this segment at the given index, scaled by the given layout size.
|
||||
@ -2141,12 +1990,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
*/
|
||||
@ForceInline
|
||||
default void setAtIndex(ValueLayout.OfDouble layout, long index, double value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
void setAtIndex(ValueLayout.OfDouble layout, long index, double value);
|
||||
|
||||
/**
|
||||
* Reads an address from this segment at the given at the given index, scaled by the given layout size. The read address is wrapped in
|
||||
@ -2171,12 +2015,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize()} overflows.
|
||||
* @throws IndexOutOfBoundsException if {@code index * byteSize() > byteSize() - layout.byteSize()}.
|
||||
*/
|
||||
@ForceInline
|
||||
default MemorySegment getAtIndex(AddressLayout layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
return (MemorySegment) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
MemorySegment getAtIndex(AddressLayout layout, long index);
|
||||
|
||||
/**
|
||||
* Writes an address into this segment at the given index, scaled by the given layout size.
|
||||
@ -2197,12 +2036,7 @@ public sealed interface MemorySegment permits AbstractMemorySegmentImpl {
|
||||
* @throws UnsupportedOperationException if this segment is {@linkplain #isReadOnly() read-only}.
|
||||
* @throws UnsupportedOperationException if {@code value} is not a {@linkplain #isNative() native} segment.
|
||||
*/
|
||||
@ForceInline
|
||||
default void setAtIndex(AddressLayout layout, long index, MemorySegment value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
// note: we know size is a small value (as it comes from ValueLayout::byteSize())
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
void setAtIndex(AddressLayout layout, long index, MemorySegment value);
|
||||
|
||||
/**
|
||||
* Compares the specified object with this memory segment for equality. Returns {@code true} if and only if the specified
|
||||
|
@ -36,6 +36,7 @@ import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.LongBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
@ -122,6 +123,12 @@ public abstract sealed class AbstractMemorySegmentImpl
|
||||
return asSliceNoCheck(offset, newSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemorySegment asSlice(long offset, MemoryLayout layout) {
|
||||
Objects.requireNonNull(layout);
|
||||
return asSlice(offset, layout.byteSize(), layout.byteAlignment());
|
||||
}
|
||||
|
||||
@Override
|
||||
@CallerSensitive
|
||||
public final MemorySegment reinterpret(long newSize, Arena arena, Consumer<MemorySegment> cleanup) {
|
||||
@ -272,6 +279,18 @@ public abstract sealed class AbstractMemorySegmentImpl
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemorySegment copyFrom(MemorySegment src) {
|
||||
MemorySegment.copy(src, 0, this, 0, src.byteSize());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long mismatch(MemorySegment other) {
|
||||
Objects.requireNonNull(other);
|
||||
return MemorySegment.mismatch(this, 0, byteSize(), other, 0, other.byteSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
throw notAMappedSegment();
|
||||
@ -732,4 +751,264 @@ public abstract sealed class AbstractMemorySegmentImpl
|
||||
throw new IllegalArgumentException("Not a supported array class: " + arrayType.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
// accessors
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public byte get(ValueLayout.OfByte layout, long offset) {
|
||||
return (byte) layout.varHandle().get(this, offset);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void set(ValueLayout.OfByte layout, long offset, byte value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public boolean get(ValueLayout.OfBoolean layout, long offset) {
|
||||
return (boolean) layout.varHandle().get(this, offset);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void set(ValueLayout.OfBoolean layout, long offset, boolean value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public char get(ValueLayout.OfChar layout, long offset) {
|
||||
return (char) layout.varHandle().get(this, offset);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void set(ValueLayout.OfChar layout, long offset, char value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public short get(ValueLayout.OfShort layout, long offset) {
|
||||
return (short) layout.varHandle().get(this, offset);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void set(ValueLayout.OfShort layout, long offset, short value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public int get(ValueLayout.OfInt layout, long offset) {
|
||||
return (int) layout.varHandle().get(this, offset);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void set(ValueLayout.OfInt layout, long offset, int value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public float get(ValueLayout.OfFloat layout, long offset) {
|
||||
return (float) layout.varHandle().get(this, offset);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void set(ValueLayout.OfFloat layout, long offset, float value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public long get(ValueLayout.OfLong layout, long offset) {
|
||||
return (long) layout.varHandle().get(this, offset);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void set(ValueLayout.OfLong layout, long offset, long value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public double get(ValueLayout.OfDouble layout, long offset) {
|
||||
return (double) layout.varHandle().get(this, offset);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void set(ValueLayout.OfDouble layout, long offset, double value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public MemorySegment get(AddressLayout layout, long offset) {
|
||||
return (MemorySegment) layout.varHandle().get(this, offset);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void set(AddressLayout layout, long offset, MemorySegment value) {
|
||||
layout.varHandle().set(this, offset, value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public byte getAtIndex(ValueLayout.OfByte layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
return (byte) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public boolean getAtIndex(ValueLayout.OfBoolean layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
return (boolean) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public char getAtIndex(ValueLayout.OfChar layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
return (char) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void setAtIndex(ValueLayout.OfChar layout, long index, char value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public short getAtIndex(ValueLayout.OfShort layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
return (short) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void setAtIndex(ValueLayout.OfByte layout, long index, byte value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void setAtIndex(ValueLayout.OfBoolean layout, long index, boolean value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void setAtIndex(ValueLayout.OfShort layout, long index, short value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public int getAtIndex(ValueLayout.OfInt layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
return (int) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void setAtIndex(ValueLayout.OfInt layout, long index, int value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public float getAtIndex(ValueLayout.OfFloat layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
return (float) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void setAtIndex(ValueLayout.OfFloat layout, long index, float value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public long getAtIndex(ValueLayout.OfLong layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
return (long) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void setAtIndex(ValueLayout.OfLong layout, long index, long value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public double getAtIndex(ValueLayout.OfDouble layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
return (double) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void setAtIndex(ValueLayout.OfDouble layout, long index, double value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public MemorySegment getAtIndex(AddressLayout layout, long index) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
return (MemorySegment) layout.varHandle().get(this, index * layout.byteSize());
|
||||
}
|
||||
|
||||
@ForceInline
|
||||
@Override
|
||||
public void setAtIndex(AddressLayout layout, long index, MemorySegment value) {
|
||||
Utils.checkElementAlignment(layout, "Layout alignment greater than its size");
|
||||
layout.varHandle().set(this, index * layout.byteSize(), value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(long offset) {
|
||||
return getString(offset, sun.nio.cs.UTF_8.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(long offset, Charset charset) {
|
||||
Objects.requireNonNull(charset);
|
||||
return StringSupport.read(this, offset, charset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setString(long offset, String str) {
|
||||
Objects.requireNonNull(str);
|
||||
setString(offset, str, sun.nio.cs.UTF_8.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setString(long offset, String str, Charset charset) {
|
||||
Objects.requireNonNull(charset);
|
||||
Objects.requireNonNull(str);
|
||||
StringSupport.write(this, offset, charset, str);
|
||||
}
|
||||
}
|
||||
|
@ -25,16 +25,26 @@
|
||||
*/
|
||||
package jdk.internal.foreign.layout;
|
||||
|
||||
import jdk.internal.foreign.LayoutPath;
|
||||
import jdk.internal.foreign.LayoutPath.PathElementImpl.PathKind;
|
||||
import jdk.internal.foreign.Utils;
|
||||
|
||||
import java.lang.foreign.GroupLayout;
|
||||
import java.lang.foreign.MemoryLayout;
|
||||
import java.lang.foreign.MemoryLayout.PathElement;
|
||||
import java.lang.foreign.SequenceLayout;
|
||||
import java.lang.foreign.StructLayout;
|
||||
import java.lang.foreign.UnionLayout;
|
||||
import java.lang.foreign.ValueLayout;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract sealed class AbstractLayout<L extends AbstractLayout<L> & MemoryLayout>
|
||||
permits AbstractGroupLayout, PaddingLayoutImpl, SequenceLayoutImpl, ValueLayouts.AbstractValueLayout {
|
||||
@ -140,4 +150,72 @@ public abstract sealed class AbstractLayout<L extends AbstractLayout<L> & Memory
|
||||
return value;
|
||||
}
|
||||
|
||||
public long scale(long offset, long index) {
|
||||
if (offset < 0) {
|
||||
throw new IllegalArgumentException("Negative offset: " + offset);
|
||||
}
|
||||
if (index < 0) {
|
||||
throw new IllegalArgumentException("Negative index: " + index);
|
||||
}
|
||||
|
||||
return Math.addExact(offset, Math.multiplyExact(byteSize(), index));
|
||||
}
|
||||
|
||||
public MethodHandle scaleHandle() {
|
||||
class Holder {
|
||||
static final MethodHandle MH_SCALE;
|
||||
static {
|
||||
try {
|
||||
MH_SCALE = MethodHandles.lookup().findVirtual(MemoryLayout.class, "scale",
|
||||
MethodType.methodType(long.class, long.class, long.class));
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Holder.MH_SCALE.bindTo(this);
|
||||
}
|
||||
|
||||
|
||||
public long byteOffset(PathElement... elements) {
|
||||
return computePathOp(LayoutPath.rootPath((MemoryLayout) this), LayoutPath::offset,
|
||||
EnumSet.of(PathKind.SEQUENCE_ELEMENT, PathKind.SEQUENCE_RANGE, PathKind.DEREF_ELEMENT), elements);
|
||||
}
|
||||
|
||||
public MethodHandle byteOffsetHandle(PathElement... elements) {
|
||||
return computePathOp(LayoutPath.rootPath((MemoryLayout) this), LayoutPath::offsetHandle,
|
||||
EnumSet.of(PathKind.DEREF_ELEMENT), elements);
|
||||
}
|
||||
|
||||
public VarHandle varHandle(PathElement... elements) {
|
||||
Objects.requireNonNull(elements);
|
||||
if (this instanceof ValueLayout vl && elements.length == 0) {
|
||||
return vl.varHandle(); // fast path
|
||||
}
|
||||
return computePathOp(LayoutPath.rootPath((MemoryLayout) this), LayoutPath::dereferenceHandle,
|
||||
Set.of(), elements);
|
||||
}
|
||||
|
||||
public MethodHandle sliceHandle(PathElement... elements) {
|
||||
return computePathOp(LayoutPath.rootPath((MemoryLayout) this), LayoutPath::sliceHandle,
|
||||
Set.of(PathKind.DEREF_ELEMENT), elements);
|
||||
}
|
||||
|
||||
public MemoryLayout select(PathElement... elements) {
|
||||
return computePathOp(LayoutPath.rootPath((MemoryLayout) this), LayoutPath::layout,
|
||||
EnumSet.of(PathKind.SEQUENCE_ELEMENT_INDEX, PathKind.SEQUENCE_RANGE, PathKind.DEREF_ELEMENT), elements);
|
||||
}
|
||||
|
||||
private static <Z> Z computePathOp(LayoutPath path, Function<LayoutPath, Z> finalizer,
|
||||
Set<PathKind> badKinds, PathElement... elements) {
|
||||
Objects.requireNonNull(elements);
|
||||
for (PathElement e : elements) {
|
||||
LayoutPath.PathElementImpl pathElem = (LayoutPath.PathElementImpl)Objects.requireNonNull(e);
|
||||
if (badKinds.contains(pathElem.kind())) {
|
||||
throw new IllegalArgumentException(String.format("Invalid %s selection in layout path", pathElem.kind().description()));
|
||||
}
|
||||
path = pathElem.apply(path);
|
||||
}
|
||||
return finalizer.apply(path);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user