java.lang.Object
jdk.incubator.foreign.MemoryHandles
public final class MemoryHandles extends Object
This class defines several factory methods for constructing and combining memory access var handles.
To obtain a memory access var handle, clients must start from one of the leaf methods
(see
varHandle(Class, ByteOrder)
,
varHandle(Class, long, ByteOrder)
). This determines the variable type
(all primitive types but void
and boolean
are supported), as well as the alignment constraint and the
byte order associated to a memory access var handle. The resulting memory access var handle can then be combined in various ways
to emulate different addressing modes. The var handles created by this class feature a mandatory coordinate type
(of type MemoryAddress
), and zero or more long
coordinate types, which can be used to emulate
multi-dimensional array indexing.
As an example, consider the memory layout expressed by a SequenceLayout
instance constructed as follows:
To access the member layout namedSequenceLayout seq = MemoryLayout.ofSequence(5, MemoryLayout.ofStruct( MemoryLayout.ofPaddingBits(32), MemoryLayout.ofValueBits(32, ByteOrder.BIG_ENDIAN).withName("value") ));
value
, we can construct a memory access var handle as follows:
VarHandle handle = MemoryHandles.varHandle(int.class, ByteOrder.BIG_ENDIAN); //(MemoryAddress) -> int handle = MemoryHandles.withOffset(handle, 4); //(MemoryAddress) -> int handle = MemoryHandles.withStride(handle, 8); //(MemoryAddress, long) -> int
Addressing mode
The final memory location accessed by a memory access var handle can be computed as follows:whereaddress = base + offset
base
denotes the address expressed by the MemoryAddress
access coordinate, and offset
can 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_n
are dynamic values provided as optional long
access coordinates, whereas c_1
, c_2
, ... c_m
and s_0
, s_1
, ... s_n
are
static constants which are can be acquired through the withOffset(VarHandle, long)
and the withStride(VarHandle, long)
combinators, respectively.
Alignment and access modes
A memory access var handle is associated with an access sizeS
and an alignment constraint B
(both expressed in bytes). We say that a memory access operation is fully aligned if it occurs
at a memory address A
which is compatible with both alignment constraints S
and B
.
If access is fully aligned then following access modes are supported and are
guaranteed to support atomic access:
- read write access modes for all
T
, with the exception of access modesget
andset
forlong
anddouble
on 32-bit platforms. - atomic update access modes for
int
,long
,float
ordouble
. (Future major platform releases of the JDK may support additional types for certain currently unsupported access modes.) - numeric atomic update access modes for
int
andlong
. (Future major platform releases of the JDK may support additional numeric types for certain currently unsupported access modes.) - bitwise atomic update access modes for
int
andlong
. (Future major platform releases of the JDK may support additional numeric types for certain currently unsupported access modes.)
T
is float
or double
then atomic
update access modes compare values using their bitwise representation
(see Float.floatToRawIntBits(float)
and
Double.doubleToRawLongBits(double)
, respectively).
Alternatively, a memory access operation is partially aligned if it occurs at a memory address A
which is only compatible with the alignment constraint B
; in such cases, access for anything other than the
get
and set
access modes will result in an IllegalStateException
. If access is partially aligned,
atomic access is only guaranteed with respect to the largest power of two that divides the GCD of A
and S
.
Finally, in all other cases, we say that a memory access operation is misaligned; in such cases an
IllegalStateException
is thrown, irrespective of the access mode being used.
-
Method Summary
Modifier and Type Method Description static VarHandle
varHandle(Class<?> carrier, long alignmentBytes, ByteOrder byteOrder)
Creates a memory access var handle with the given carrier type, alignment constraint, and byte order.static VarHandle
varHandle(Class<?> carrier, ByteOrder byteOrder)
Creates a memory access var handle with the given carrier type and byte order.static VarHandle
withOffset(VarHandle target, long bytesOffset)
Creates a memory access var handle with a fixed offset added to the accessed offset.static VarHandle
withStride(VarHandle target, long bytesStride)
Creates a memory access var handle with a variable offset added to the accessed offset.
-
Method Details
-
varHandle
Creates a memory access var handle with the given carrier type and byte order. The resulting memory access var handle features a singleMemoryAddress
access coordinate, and its variable type is set by the given carrier type. The alignment constraint for the resulting memory access var handle is the same as the in memory size of the carrier type, and the accessed offset is set at zero.- API Note:
- the resulting var handle features certain access mode restrictions, which are common to all memory access var handles.
- Parameters:
carrier
- the carrier type. Valid carriers arebyte
,short
,char
,int
,float
,long
, anddouble
.byteOrder
- the required byte order.- Returns:
- the new memory access var handle.
- Throws:
IllegalArgumentException
- when an illegal carrier type is used
-
varHandle
Creates a memory access var handle with the given carrier type, alignment constraint, and byte order. The resulting memory access var handle features a singleMemoryAddress
access coordinate, and its variable type is set by the given carrier type. The accessed offset is zero.- API Note:
- the resulting var handle features certain access mode restrictions, which are common to all memory access var handles.
- Parameters:
carrier
- the carrier type. Valid carriers arebyte
,short
,char
,int
,float
,long
, anddouble
.alignmentBytes
- the alignment constraint (in bytes). Must be a power of two.byteOrder
- the required byte order.- Returns:
- the new memory access var handle.
- Throws:
IllegalArgumentException
- if an illegal carrier type is used, or ifalignmentBytes
is not a power of two.
-
withOffset
Creates a memory access var handle with a fixed offset added to the accessed offset. That is, if the target memory access var handle accesses a memory location at offset O, the new memory access var handle will access a memory location at offset O' + O. The resulting memory access var handle will feature the same access coordinates as the ones in the target memory access var handle.- API Note:
- the resulting var handle features certain access mode restrictions, which are common to all memory access var handles.
- Parameters:
target
- the target memory access handle to access after the offset adjustment.bytesOffset
- the offset, in bytes. Must be positive or zero.- Returns:
- the new memory access var handle.
- Throws:
IllegalArgumentException
- when the target var handle is not a memory access var handle, or whenbytesOffset < 0
, or otherwise incompatible with the alignment constraint.
-
withStride
Creates a memory access var handle with a variable offset added to the accessed offset. That is, if the target memory access var handle accesses a memory location at offset O, the new memory access var handle will access a memory location at offset (S * X) + O, where S is a constant stride, whereas X is a dynamic value that will be provided as an additional access coordinate (of typelong
). The new access coordinate will be prepended to the ones available in the target memory access var handles (if any).- API Note:
- the resulting var handle features certain access mode restrictions, which are common to all memory access var handles.
- Parameters:
target
- the target memory access handle to access after the scale adjustment.bytesStride
- the stride, in bytes, by which to multiply the coordinate value. Must be greater than zero.- Returns:
- the new memory access var handle.
- Throws:
IllegalArgumentException
- when the target var handle is not a memory access var handle, or ifbytesStride <= 0
, or otherwise incompatible with the alignment constraint.
-