- All Superinterfaces:
- Constable
- All Known Implementing Classes:
- GroupLayout,- SequenceLayout,- ValueLayout,- ValueLayout.OfAddress,- ValueLayout.OfBoolean,- ValueLayout.OfByte,- ValueLayout.OfChar,- ValueLayout.OfDouble,- ValueLayout.OfFloat,- ValueLayout.OfInt,- ValueLayout.OfLong,- ValueLayout.OfShort
ValueLayout) and padding layouts which are used, as the name suggests, to represent a portion of a memory
 segment whose contents should be ignored, and which are primarily present for alignment reasons (see paddingLayout(long)).
 Some common value layout constants are defined in the ValueLayout class.
 
 More complex layouts can be derived from simpler ones: a sequence layout denotes a repetition of one or more
 element layout (see SequenceLayout); a group layout denotes an aggregation of (typically) heterogeneous
 member layouts (see GroupLayout).
 
For instance, consider the following struct declaration in C:
typedef struct {
    char kind;
    int value;
} TaggedValues[5];
SequenceLayout taggedValues = MemoryLayout.sequenceLayout(5,
    MemoryLayout.structLayout(
        ValueLayout.JAVA_BYTE.withName("kind"),
        MemoryLayout.paddingLayout(24),
        ValueLayout.JAVA_INT.withName("value")
    )
).withName("TaggedValues");
 All implementations of this interface must be value-based;
 programmers should treat instances that are equal as interchangeable and should not
 use instances for synchronization, or unpredictable behavior may occur. For example, in a future release,
 synchronization may fail. The equals method should be used for comparisons.
 
 Unless otherwise specified, passing a null argument, or an array argument containing one or more null
 elements to a method in this class causes a NullPointerException to be thrown. 
Size, alignment and byte order
All layouts have a size; layout size for value and padding layouts is always explicitly denoted; this means that a layout description always has the same size in bits, regardless of the platform in which it is used. For derived layouts, the size is computed as follows:- for a finite sequence layout S whose element layout is E and size is L, the size of S is that of E, multiplied by L
- the size of an unbounded sequence layout is unknown
- for a group layout G with member layouts M1, M2, ... Mn whose sizes are S1, S2, ... Sn, respectively, the size of G is either S1 + S2 + ... + Sn or max(S1, S2, ... Sn) depending on whether the group is a struct or an union, respectively
Furthermore, all layouts feature a natural alignment which can be inferred as follows:
- for a padding layout L, the natural alignment is 1, regardless of its size; that is, in the absence of an explicit alignment constraint, a padding layout should not affect the alignment constraint of the group layout it is nested into
- for a value layout L whose size is N, the natural alignment of L is N
- for a sequence layout S whose element layout is E, the natural alignment of S is that of E
- for a group layout G with member layouts M1, M2, ... Mn whose alignments are A1, A2, ... An, respectively, the natural alignment of G is max(A1, A2 ... An)
withBitAlignment(long)), which can be useful to describe
 hyper-aligned layouts.
 
 All value layouts have an explicit byte order (see ByteOrder) which is set when the layout is created.
 
Layout paths
A layout path originates from a root layout (typically a group or a sequence layout) and terminates at a layout nested within the root layout - this is the layout selected by the layout path. Layout paths are typically expressed as a sequence of one or moreMemoryLayout.PathElement instances.
 
 Layout paths are for example useful in order to obtain offsets of
 arbitrarily nested layouts inside another layout, to quickly obtain a memory access handle
 corresponding to the selected layout, to select an arbitrarily nested layout inside
 another layout, or to transform a nested layout element inside
 another layout.
 
 Such layout paths can be constructed programmatically using the methods in this class.
 For instance, given the taggedValues layout instance constructed as above, we can obtain the offset,
 in bits, of the member layout named value in the first sequence element, as follows:
 
long valueOffset = taggedValues.bitOffset(PathElement.sequenceElement(0),
                                          PathElement.groupElement("value")); // yields 32
value, as follows:
 
MemoryLayout value = taggedValues.select(PathElement.sequenceElement(),
                                         PathElement.groupElement("value"));
value with another layout, as follows:
 
MemoryLayout taggedValuesWithHole = taggedValues.map(l -> MemoryLayout.paddingLayout(32),
                                            PathElement.sequenceElement(), PathElement.groupElement("value"));
MemoryLayout taggedValuesWithHole = MemoryLayout.sequenceLayout(5,
    MemoryLayout.structLayout(
        ValueLayout.JAVA_BYTE.withName("kind"),
        MemoryLayout.paddingLayout(32),
        MemoryLayout.paddingLayout(32)
));
MemoryLayout.PathElement.sequenceElement() method) features an additional free dimension, which will have to be bound at runtime.
 This is important when obtaining memory access var handle from layouts, as in the following code:
 
VarHandle valueHandle = taggedValues.varHandle(PathElement.sequenceElement(),
                                               PathElement.groupElement("value"));
value should be selected from the enclosing sequence layout),
 it follows that the memory access var handle valueHandle will feature an additional long
 access coordinate.
 A layout path with free dimensions can also be used to create an offset-computing method handle, using the
 bitOffset(PathElement...) or byteOffsetHandle(PathElement...) method. Again, free dimensions are
 translated into long parameters of the created method handle. The method handle can be used to compute the
 offsets of elements of a sequence at different indices, by supplying these indices when invoking the method handle.
 For instance:
 
MethodHandle offsetHandle = taggedValues.byteOffsetHandle(PathElement.sequenceElement(),
                                                          PathElement.groupElement("kind"));
long offset1 = (long) offsetHandle.invokeExact(1L); // 8
long offset2 = (long) offsetHandle.invokeExact(2L); // 16
Layout attributes
Layouts can be optionally associated with a name. A layout name can be referred to when constructing layout paths.- Implementation Requirements:
- Implementations of this interface are immutable, thread-safe and value-based.
- 
Nested Class SummaryNested ClassesModifier and TypeInterfaceDescriptionstatic interfaceInstances of this class are used to form layout paths.
- 
Method SummaryModifier and TypeMethodDescriptionlongReturns the alignment constraint associated with this layout, expressed in bits.default longbitOffset(MemoryLayout.PathElement... elements) Computes the offset, in bits, of the layout selected by a given layout path, where the path is considered rooted in this layout.default MethodHandlebitOffsetHandle(MemoryLayout.PathElement... elements) Creates a method handle that can be used to compute the offset, in bits, of the layout selected by a given layout path, where the path is considered rooted in this layout.longbitSize()Returns the layout size, in bits.default longReturns the alignment constraint associated with this layout, expressed in bytes.default longbyteOffset(MemoryLayout.PathElement... elements) Computes the offset, in bytes, of the layout selected by a given layout path, where the path is considered rooted in this layout.default MethodHandlebyteOffsetHandle(MemoryLayout.PathElement... elements) Creates a method handle that can be used to compute the offset, in bytes, of the layout selected by a given layout path, where the path is considered rooted in this layout.longbyteSize()Returns the layout size, in bytes.Optional<? extends DynamicConstantDesc<? extends MemoryLayout>>booleanCompares the specified object with this layout for equality.inthashCode()Returns the hash code value for this layout.booleanhasSize()Returnstrueif this layout has a specified size.booleanReturns true, if this layout is a padding layout.default MemoryLayoutmap(UnaryOperator<MemoryLayout> op, MemoryLayout.PathElement... elements) Creates a transformed copy of this layout where a selected layout, from a path rooted in this layout, is replaced with the result of applying the given operation.name()Returns the name (if any) associated with this layout.static MemoryLayoutpaddingLayout(long size) Create a new padding layout with given size.default MemoryLayoutselect(MemoryLayout.PathElement... elements) Selects the layout from a path rooted in this layout.static SequenceLayoutsequenceLayout(long elementCount, MemoryLayout elementLayout) Create a new sequence layout with given element layout and element count.static SequenceLayoutsequenceLayout(MemoryLayout elementLayout) Create a new sequence layout, with unbounded element count and given element layout.default MethodHandlesliceHandle(MemoryLayout.PathElement... elements) Creates a method handle which, given a memory segment, returns a slice corresponding to the layout selected by a given layout path, where the path is considered rooted in this layout.static GroupLayoutstructLayout(MemoryLayout... elements) Create a new struct group layout with given member layouts.toString()Returns the string representation of this layout.static GroupLayoutunionLayout(MemoryLayout... elements) Create a new union group layout with given member layouts.static ValueLayoutvalueLayout(Class<?> carrier, ByteOrder order) Creates a value layout of given Java carrier and byte order.default VarHandlevarHandle(MemoryLayout.PathElement... elements) Creates a memory access var handle that can be used to dereference memory at the layout selected by a given layout path, where the path is considered rooted in this layout.withBitAlignment(long bitAlignment) Creates a new layout which features the desired alignment constraint.Creates a new layout which features the desired layout name.
- 
Method Details- 
describeConstableOptional<? extends DynamicConstantDesc<? extends MemoryLayout>> describeConstable()Returns anOptionalcontaining the nominal descriptor for this layout, if one can be constructed, or an emptyOptionalif one cannot be constructed.- Specified by:
- describeConstablein interface- Constable
- Returns:
- an Optionalcontaining the nominal descriptor for this layout, if one can be constructed, or an emptyOptionalif one cannot be constructed
 
- 
hasSizeboolean hasSize()Returnstrueif this layout has a specified size. A layout does not have a specified size if it is (or contains) a sequence layout whose size is unspecified (seeSequenceLayout.elementCount()). Value layouts (seeValueLayout) and padding layouts (seepaddingLayout(long)) always have a specified size, therefore this method always returnstruein these cases.- Returns:
- true, if this layout has a specified size.
 
- 
bitSizelong bitSize()Returns the layout size, in bits.- Returns:
- the layout size, in bits
- Throws:
- UnsupportedOperationException- if the layout is, or contains, a sequence layout with unspecified size (see- SequenceLayout).
 
- 
byteSizelong byteSize()Returns the layout size, in bytes.- Returns:
- the layout size, in bytes
- Throws:
- UnsupportedOperationException- if the layout is, or contains, a sequence layout with unspecified size (see- SequenceLayout), or if- bitSize()is not a multiple of 8.
 
- 
nameReturns the name (if any) associated with this layout.- Returns:
- the name (if any) associated with this layout
- See Also:
 
- 
withNameCreates a new layout which features the desired layout name.- Parameters:
- name- the layout name.
- Returns:
- a new layout which is the same as this layout, except for the name associated with it.
- See Also:
 
- 
bitAlignmentlong bitAlignment()Returns the alignment constraint associated with this layout, expressed in bits. Layout alignment defines a power of twoAwhich is the bit-wise alignment of the layout. IfA <= 8thenA/8is the number of bytes that must be aligned for any pointer that correctly points to this layout. Thus:- A=8means unaligned (in the usual sense), which is common in packets.
- A=64means word aligned (on LP64),- A=32int aligned,- A=16short aligned, etc.
- A=512is the most strict alignment required by the x86/SV ABI (for AVX-512 data).
 withBitAlignment(long)), then this method returns the natural alignment constraint (in bits) associated with this layout.- Returns:
- the layout alignment constraint, in bits.
 
- 
byteAlignmentdefault long byteAlignment()Returns the alignment constraint associated with this layout, expressed in bytes. Layout alignment defines a power of twoAwhich is the byte-wise alignment of the layout, whereAis the number of bytes that must be aligned for any pointer that correctly points to this layout. Thus:- A=1means unaligned (in the usual sense), which is common in packets.
- A=8means word aligned (on LP64),- A=4int aligned,- A=2short aligned, etc.
- A=64is the most strict alignment required by the x86/SV ABI (for AVX-512 data).
 withBitAlignment(long)), then this method returns the natural alignment constraint (in bytes) associated with this layout.- Returns:
- the layout alignment constraint, in bytes.
- Throws:
- UnsupportedOperationException- if- bitAlignment()is not a multiple of 8.
 
- 
withBitAlignmentCreates a new layout which features the desired alignment constraint.- Parameters:
- bitAlignment- the layout alignment constraint, expressed in bits.
- Returns:
- a new layout which is the same as this layout, except for the alignment constraint associated with it.
- Throws:
- IllegalArgumentException- if- bitAlignmentis not a power of two, or if it's less than 8.
 
- 
bitOffsetComputes the offset, in bits, of the layout selected by a given layout path, where the path is considered rooted in this layout.- Parameters:
- elements- the layout path elements.
- Returns:
- The offset, in bits, of the layout selected by the layout path in elements.
- Throws:
- IllegalArgumentException- if the layout path does not select any layout nested in this layout, or if the layout path contains one or more path elements that select multiple sequence element indices (see- MemoryLayout.PathElement.sequenceElement()and- MemoryLayout.PathElement.sequenceElement(long, long)).
- UnsupportedOperationException- if one of the layouts traversed by the layout path has unspecified size.
- NullPointerException- if either- elements == null, or if any of the elements in- elementsis- null.
 
- 
bitOffsetHandleCreates a method handle that can be used to compute the offset, in bits, of the layout selected by a given layout path, where the path is considered rooted in this layout.The returned method handle has a return type of long, and features as manylongparameter types as there are free dimensions in the provided layout path (seeMemoryLayout.PathElement.sequenceElement()), where the order of the parameters corresponds to the order of the path elements. The returned method handle can be used to compute a layout offset similar tobitOffset(PathElement...), but where some sequence indices are specified only when invoking the method handle.The final offset returned by the method handle is computed as follows: 
 whereoffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)x_1,x_2, ...x_nare dynamic values provided aslongarguments, whereasc_1,c_2, ...c_mare static offset constants ands_0,s_1, ...s_nare static stride constants which are derived from the layout path.- Parameters:
- elements- the layout path elements.
- Returns:
- a method handle that can be used to compute the bit offset of the layout element specified by the given layout path elements, when supplied with the missing sequence element indices.
- Throws:
- IllegalArgumentException- if the layout path contains one or more path elements that select multiple sequence element indices (see- MemoryLayout.PathElement.sequenceElement(long, long)).
- UnsupportedOperationException- if one of the layouts traversed by the layout path has unspecified size.
 
- 
byteOffsetComputes the offset, in bytes, of the layout selected by a given layout path, where the path is considered rooted in this layout.- Parameters:
- elements- the layout path elements.
- Returns:
- The offset, in bytes, of the layout selected by the layout path in elements.
- Throws:
- IllegalArgumentException- if the layout path does not select any layout nested in this layout, or if the layout path contains one or more path elements that select multiple sequence element indices (see- MemoryLayout.PathElement.sequenceElement()and- MemoryLayout.PathElement.sequenceElement(long, long)).
- UnsupportedOperationException- if one of the layouts traversed by the layout path has unspecified size, or if- bitOffset(elements)is not a multiple of 8.
- NullPointerException- if either- elements == null, or if any of the elements in- elementsis- null.
 
- 
byteOffsetHandleCreates a method handle that can be used to compute the offset, in bytes, of the layout selected by a given layout path, where the path is considered rooted in this layout.The returned method handle has a return type of long, and features as manylongparameter types as there are free dimensions in the provided layout path (seeMemoryLayout.PathElement.sequenceElement()), where the order of the parameters corresponds to the order of the path elements. The returned method handle can be used to compute a layout offset similar tobyteOffset(PathElement...), but where some sequence indices are specified only when invoking the method handle.The final offset returned by the method handle is computed as follows: 
 wherebitOffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n) offset = bitOffset / 8x_1,x_2, ...x_nare dynamic values provided aslongarguments, whereasc_1,c_2, ...c_mare static offset constants ands_0,s_1, ...s_nare static stride constants which are derived from the layout path.The method handle will throw an UnsupportedOperationExceptionif the computed offset in bits is not a multiple of 8.- Parameters:
- elements- the layout path elements.
- Returns:
- a method handle that can be used to compute the byte offset of the layout element specified by the given layout path elements, when supplied with the missing sequence element indices.
- Throws:
- IllegalArgumentException- if the layout path contains one or more path elements that select multiple sequence element indices (see- MemoryLayout.PathElement.sequenceElement(long, long)).
- UnsupportedOperationException- if one of the layouts traversed by the layout path has unspecified size.
 
- 
varHandleCreates a memory access var handle that can be used to dereference memory at the layout selected by a given layout path, where the path is considered rooted in this layout.The final memory location accessed by the returned memory access var handle can be computed as follows: 
 whereaddress = base + offsetbasedenotes the base address expressed by theMemorySegmentaccess coordinate (seeMemorySegment.address()andMemoryAddress.toRawLongValue()) andoffsetcan be expressed in the following form:
 whereoffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n)x_1,x_2, ...x_nare dynamic values provided aslongarguments, whereasc_1,c_2, ...c_mare static offset constants ands_0,s_1, ...s_nare static stride constants which are derived from the layout path.- API Note:
- the resulting var handle will feature an additional longaccess coordinate for every unspecified sequence access component contained in this layout path. Moreover, the resulting var handle features certain access mode restrictions, which are common to all memory access var handles.
- Parameters:
- elements- the layout path elements.
- Returns:
- a var handle which can be used to dereference memory at the (possibly nested) layout selected by the layout path in elements.
- Throws:
- UnsupportedOperationException- if the layout path has one or more elements with incompatible alignment constraints, or if one of the layouts traversed by the layout path has unspecified size.
- IllegalArgumentException- if the layout path in- elementsdoes not select a value layout (see- ValueLayout).
 
- 
sliceHandleCreates a method handle which, given a memory segment, returns a slice corresponding to the layout selected by a given layout path, where the path is considered rooted in this layout.The returned method handle has a return type of MemorySegment, features aMemorySegmentparameter as leading parameter representing the segment to be sliced, and features as many trailinglongparameter types as there are free dimensions in the provided layout path (seeMemoryLayout.PathElement.sequenceElement()), where the order of the parameters corresponds to the order of the path elements. The returned method handle can be used to create a slice similar to usingMemorySegment.asSlice(long, long), but where the offset argument is dynamically compute based on indices specified when invoking the method handle.The offset of the returned segment is computed as follows: 
 wherebitOffset = c_1 + c_2 + ... + c_m + (x_1 * s_1) + (x_2 * s_2) + ... + (x_n * s_n) offset = bitOffset / 8x_1,x_2, ...x_nare dynamic values provided aslongarguments, whereasc_1,c_2, ...c_mare static offset constants ands_0,s_1, ...s_nare static stride constants which are derived from the layout path.After the offset is computed, the returned segment is created as if by calling: wheresegment.asSlice(offset, layout.byteSize());segmentis the segment to be sliced, and wherelayoutis the layout selected by the given layout path, as perselect(PathElement...).The method handle will throw an UnsupportedOperationExceptionif the computed offset in bits is not a multiple of 8.- Parameters:
- elements- the layout path elements.
- Returns:
- a method handle which can be used to create a slice of the selected layout element, given a segment.
- Throws:
- UnsupportedOperationException- if the size of the selected layout in bits is not a multiple of 8.
 
- 
selectSelects the layout from a path rooted in this layout.- Parameters:
- elements- the layout path elements.
- Returns:
- the layout selected by the layout path in elements.
- Throws:
- IllegalArgumentException- if the layout path does not select any layout nested in this layout, or if the layout path contains one or more path elements that select one or more sequence element indices (see- MemoryLayout.PathElement.sequenceElement(long)and- MemoryLayout.PathElement.sequenceElement(long, long)).
 
- 
mapCreates a transformed copy of this layout where a selected layout, from a path rooted in this layout, is replaced with the result of applying the given operation.- Parameters:
- op- the unary operation to be applied to the selected layout.
- elements- the layout path elements.
- Returns:
- a new layout where the layout selected by the layout path in elements, has been replaced by the result of applyingopto the selected layout.
- Throws:
- IllegalArgumentException- if the layout path does not select any layout nested in this layout, or if the layout path contains one or more path elements that select one or more sequence element indices (see- MemoryLayout.PathElement.sequenceElement(long)and- MemoryLayout.PathElement.sequenceElement(long, long)).
 
- 
isPaddingboolean isPadding()Returns true, if this layout is a padding layout.- Returns:
- true, if this layout is a padding layout
 
- 
equalsCompares the specified object with this layout for equality. Returnstrueif and only if the specified object is also a layout, and it is equal to this layout. Two layouts are considered equal if they are of the same kind, have the same size, name and alignment constraints. Furthermore, depending on the layout kind, additional conditions must be satisfied:- two value layouts are considered equal if they have the same byte order (see ValueLayout.order())
- two sequence layouts are considered equal if they have the same element count (see SequenceLayout.elementCount()), and if their element layouts (seeSequenceLayout.elementLayout()) are also equal
- two group layouts are considered equal if they are of the same kind (see GroupLayout.isStruct(),GroupLayout.isUnion()) and if their member layouts (seeGroupLayout.memberLayouts()) are also equal
 
- two value layouts are considered equal if they have the same byte order (see 
- 
hashCodeint hashCode()Returns the hash code value for this layout.
- 
toStringString toString()Returns the string representation of this layout.
- 
paddingLayoutCreate a new padding layout with given size.- Parameters:
- size- the padding size in bits.
- Returns:
- the new selector layout.
- Throws:
- IllegalArgumentException- if- size <= 0.
 
- 
valueLayoutCreates a value layout of given Java carrier and byte order. The type of resulting value layout is determined by the carrier provided:- ValueLayout.OfBoolean, for- boolean.class
- ValueLayout.OfByte, for- byte.class
- ValueLayout.OfShort, for- short.class
- ValueLayout.OfChar, for- char.class
- ValueLayout.OfInt, for- int.class
- ValueLayout.OfFloat, for- float.class
- ValueLayout.OfLong, for- long.class
- ValueLayout.OfDouble, for- double.class
- ValueLayout.OfAddress, for- MemoryAddress.class
 - Parameters:
- carrier- the value layout carrier.
- order- the value layout's byte order.
- Returns:
- a new value layout.
- Throws:
- IllegalArgumentException- if the carrier type is not supported.
 
- 
sequenceLayoutCreate a new sequence layout with given element layout and element count.- Parameters:
- elementCount- the sequence element count.
- elementLayout- the sequence element layout.
- Returns:
- the new sequence layout with given element layout and size.
- Throws:
- IllegalArgumentException- if- elementCount < 0.
 
- 
sequenceLayoutCreate a new sequence layout, with unbounded element count and given element layout.- Parameters:
- elementLayout- the element layout of the sequence layout.
- Returns:
- the new sequence layout with given element layout.
 
- 
structLayoutCreate a new struct group layout with given member layouts.- Parameters:
- elements- The member layouts of the struct group layout.
- Returns:
- a new struct group layout with given member layouts.
 
- 
unionLayoutCreate a new union group layout with given member layouts.- Parameters:
- elements- The member layouts of the union layout.
- Returns:
- a new union group layout with given member layouts.
 
 
-