- All Superinterfaces:
- Constable
- All Known Implementing Classes:
- GroupLayout,- SequenceLayout,- ValueLayout
public interface MemoryLayout extends Constable
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 ofPaddingBits(long)).
 Some common value layout constants are defined in the MemoryLayouts 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).
 
 All implementations of this interface must be value-based;
 use of identity-sensitive operations (including reference equality (==), identity hash code, or synchronization) on
 instances of MemoryLayout may have unpredictable results and should be avoided. The equals method should
 be used for comparisons.
 
Non-platform classes should not implement MemoryLayout directly.
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 value and padding 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
 (see offset(PathElement...)), to quickly obtain a memory access handle corresponding to the selected
 layout (see varHandle(Class, PathElement...)), to select an arbitrarily nested layout inside
 another layout (see select(PathElement...), or to transform a nested layout element inside
 another layout (see map(UnaryOperator, PathElement...)).
 
Such layout paths can be constructed programmatically using the methods in this class. For instance, given a layout constructed as follows:
We can obtain the offset of the member layout namedSequenceLayout seq = MemoryLayout.ofSequence(5, MemoryLayout.ofStruct( MemoryLayout.ofPaddingBits(32), MemoryLayout.ofValueBits(32, ByteOrder.BIG_ENDIAN).withName("value") ));
value from seq, as follows:
 Similarly, we can select the member layout namedlong valueOffset = seq.addOffset(PathElement.sequenceElement(), PathElement.groupElement("value"));
value, as follows:
 And, we can also replace the layout namedMemoryLayout value = seq.select(PathElement.sequenceElement(), PathElement.groupElement("value"));
value with another layout, as follows:
 That is, the above declaration is identical to the following, more verbose one:MemoryLayout newSeq = seq.map(l -> MemoryLayout.ofPadding(32), PathElement.sequenceElement(), PathElement.groupElement("value"));
Layout paths can feature one or more free dimensions. For instance, a layout path traversing an unspecified sequence element (that is, where one of the path component was obtained with theMemoryLayout newSeq = MemoryLayout.ofSequence(5, MemoryLayout.ofStruct( MemoryLayout.ofPaddingBits(32), MemoryLayout.ofPaddingBits(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:
 Since the layout pathVarHandle valueHandle = seq.map(int.class, PathElement.sequenceElement(), PathElement.groupElement("value"));
seq constructed in the above example features exactly one free dimension,
 it follows that the memory access var handle valueHandle will feature an extra long
 access coordinate.- API Note:
- In the future, if the Java language permits, MemoryLayoutmay become asealedinterface, which would prohibit subclassing except by explicitly permitted types.
- Implementation Requirements:
- Implementations of this class are immutable and thread-safe.
- 
Nested Class SummaryNested Classes Modifier and Type Interface Description static interfaceMemoryLayout.PathElementInstances of this class are used to form layout paths.
- 
Method SummaryModifier and Type Method Description longbitAlignment()Returns the alignment constraint associated with this layout, expressed in bits.longbitSize()Computes the layout size, in bits.default longbyteAlignment()Returns the alignment constraint associated with this layout, expressed in bytes.default longbyteSize()Computes the layout size, in bytes.Optional<? extends DynamicConstantDesc<? extends MemoryLayout>>describeConstable()booleanequals(Object that)Compares the specified object with this layout for equality.inthashCode()Returns the hash code value for this layout.booleanhasSize()Does this layout have a specified size?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.Optional<String>name()Return the name (if any) associated with this layout.default longoffset(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.static MemoryLayoutofPaddingBits(long size)Create a new padding layout with given size.static SequenceLayoutofSequence(long elementCount, MemoryLayout elementLayout)Create a new sequence layout with given element layout and element count.static SequenceLayoutofSequence(MemoryLayout elementLayout)Create a new sequence layout, with unbounded element count and given element layout.static GroupLayoutofStruct(MemoryLayout... elements)Create a new struct group layout with given member layouts.static GroupLayoutofUnion(MemoryLayout... elements)Create a new union group layout with given member layouts.static ValueLayoutofValueBits(long size, ByteOrder order)Create a value layout of given byte order and size.default MemoryLayoutselect(MemoryLayout.PathElement... elements)Selects the layout from a path rooted in this layout.StringtoString()Returns a string representation of this layout.default VarHandlevarHandle(Class<?> carrier, 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.MemoryLayoutwithBitAlignment(long bitAlignment)Creates a new layout which features the desired alignment constraint.MemoryLayoutwithName(String name)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 resulting nominal descriptor, or an emptyOptionalif one cannot be constructed.
 
- 
hasSizeboolean hasSize()Does this layout have 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 (seeofPaddingBits(long)) always have a specified size, therefore this method always returnstruein these cases.- Returns:
- true, if this layout has a specified size.
 
- 
bitSizelong bitSize()Computes 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).
 
- 
byteSizedefault long byteSize()Computes 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.
 
- 
nameReturn the name (if any) associated with this layout.- Returns:
- the layout name (if any).
- See Also:
- withName(String)
 
- 
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 to it.
- See Also:
- name()
 
- 
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 to it.
- Throws:
- IllegalArgumentException- if- bitAlignmentis not a power of two, or if it's less than than 8.
 
- 
offsetComputes the offset, in bits, of the layout selected by a given layout path, where the path is considered rooted in this layout.- API Note:
- if the layout path has one (or more) free dimensions,
 the offset is computed as if all the indices corresponding to such dimensions were set to 0.
- 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.
 
- 
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.- 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:
- carrier- the var handle carrier type.
- 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 carrier does not represent a primitive type, if the carrier is- void,- boolean, or if the layout path in- elementsdoes not select a value layout (see- ValueLayout), or if the selected value layout has a size that that does not match that of the specified carrier type.
 
- 
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)).
 
- 
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 endianness (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
 - Overrides:
- equalsin class- Object
- Parameters:
- that- the object to be compared for equality with this layout.
- Returns:
- trueif the specified object is equal to this layout.
- See Also:
- Object.hashCode(),- HashMap
 
- two value layouts are considered equal if they have the same endianness (see 
- 
hashCodeint hashCode()Returns the hash code value for this layout.- Overrides:
- hashCodein class- Object
- Returns:
- the hash code value for this layout.
- See Also:
- Object.equals(java.lang.Object),- System.identityHashCode(java.lang.Object)
 
- 
toStringString toString()Returns a string representation of this layout.
- 
ofPaddingBitsCreate a new padding layout with given size.- Parameters:
- size- the padding size in bits.
- Returns:
- the new selector layout.
- Throws:
- IllegalArgumentException- if- size <= 0.
 
- 
ofValueBitsCreate a value layout of given byte order and size.- Parameters:
- size- the value layout size.
- order- the value layout's byte order.
- Returns:
- a new value layout.
- Throws:
- IllegalArgumentException- if- size <= 0.
 
- 
ofSequenceCreate 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.
 
- 
ofSequenceCreate 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.
 
- 
ofStructCreate 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.
 
- 
ofUnionCreate 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.
 
 
-