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 MemorySegment
), and one long
coordinate type, which represents the offset, in bytes, relative
to the segment, at which dereference should occur.
As an example, consider the memory layout expressed by a GroupLayout
instance constructed as follows:
To access the member layout namedGroupLayout seq = 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); //(MemorySegment, long) -> int handle = MemoryHandles.insertCoordinates(handle, 1, 4); //(MemorySegment) -> int
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.
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 TypeMethodDescriptionstatic VarHandle
asAddressVarHandle(VarHandle target)
Adapt an existing var handle into a new var handle whose carrier type isMemorySegment
.static VarHandle
asUnsigned(VarHandle target, Class<?> adaptedType)
Adapts a target var handle by narrowing incoming values and widening outgoing values, to and from the given type, respectively.static VarHandle
collectCoordinates(VarHandle target, int pos, MethodHandle filter)
Adapts a target var handle handle by pre-processing a sub-sequence of its coordinate values with a filter (a method handle).static VarHandle
dropCoordinates(VarHandle target, int pos, Class<?>... valueTypes)
Returns a var handle which will discard some dummy coordinates before delegating to the target var handle.static VarHandle
filterCoordinates(VarHandle target, int pos, MethodHandle... filters)
Adapts a target var handle by pre-processing incoming coordinate values using unary filter functions.static VarHandle
filterValue(VarHandle target, MethodHandle filterToTarget, MethodHandle filterFromTarget)
Adapts a target var handle by pre-processing incoming and outgoing values using a pair of filter functions.static VarHandle
insertCoordinates(VarHandle target, int pos, Object... values)
Provides a target var handle with one or more bound coordinates in advance of the var handle's invocation.static VarHandle
permuteCoordinates(VarHandle target, List<Class<?>> newCoordinates, int... reorder)
Provides a var handle which adapts the coordinate values of the target var handle, by re-arranging them so that the new coordinates match the provided ones.static VarHandle
Creates a memory access var handle with the given carrier type, alignment constraint, and byte order.static VarHandle
Creates a memory access var handle with the given carrier type and byte order.
-
Method Details
-
varHandle
Creates a memory access var handle with the given carrier type and byte order. The returned var handle's type iscarrier
and the list of coordinate types is(MemorySegment, long)
, where thelong
coordinate type corresponds to byte offset into a given memory segment. The returned var handle accesses bytes at an offset in a given memory segment, composing bytes to or from a value of the typecarrier
according to the given endianness; the alignment constraint (in bytes) for the resulting memory access var handle is the same as the size (in bytes) of the carrier typecarrier
.- 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 returned var handle's type iscarrier
and the list of coordinate types is(MemorySegment, long)
, where thelong
coordinate type corresponds to byte offset into a given memory segment. The returned var handle accesses bytes at an offset in a given memory segment, composing bytes to or from a value of the typecarrier
according to the given endianness; the alignment constraint (in bytes) for the resulting memory access var handle is given byalignmentBytes
.- 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.
-
asAddressVarHandle
Adapt an existing var handle into a new var handle whose carrier type isMemorySegment
. That is, when callingVarHandle.get(Object...)
on the returned var handle, the read numeric value will be turned into a memory address (as if by callingMemoryAddress.ofLong(long)
); similarly, when callingVarHandle.set(Object...)
, the memory address to be set will be converted into a numeric value, and then written into memory. The amount of bytes read (resp. written) from (resp. to) memory depends on the carrier of the original memory access var handle.- Parameters:
target
- the memory access var handle to be adapted- Returns:
- the adapted var handle.
- Throws:
IllegalArgumentException
- if the carrier type ofvarHandle
is eitherboolean
,float
, ordouble
, or is not a primitive type.
-
asUnsigned
Adapts a target var handle by narrowing incoming values and widening outgoing values, to and from the given type, respectively.The returned var handle can be used to conveniently treat unsigned primitive data types as if they were a wider signed primitive type. For example, it is often convenient to model an unsigned short as a Java
int
to avoid dealing with negative values, which would be the case if modeled as a Javashort
. This is illustrated in the following example:MemorySegment segment = MemorySegment.allocateNative(2); VarHandle SHORT_VH = MemoryLayouts.JAVA_SHORT.varHandle(short.class); VarHandle INT_VH = MemoryHandles.asUnsigned(SHORT_VH, int.class); SHORT_VH.set(segment, (short)-1); INT_VH.get(segment); // returns 65535
When calling e.g.
VarHandle.set(Object...)
on the resulting var handle, the incoming value (of typeadaptedType
) is converted by a narrowing primitive conversion and then passed to thetarget
var handle. A narrowing primitive conversion may lose information about the overall magnitude of a numeric value. Conversely, when calling e.g.VarHandle.get(Object...)
on the resulting var handle, the returned value obtained from thetarget
var handle is converted by a unsigned widening conversion before being returned to the caller. In an unsigned widening conversion the high-order bits greater than that of thetarget
carrier type are zero, and the low-order bits (equal to the width of thetarget
carrier type) are equal to the bits of the value obtained from thetarget
var handle.The returned var handle will feature the variable type
adaptedType
, and the same access coordinates, the same access modes (seeVarHandle.AccessMode
, and the same atomic access guarantees, as those featured by thetarget
var handle.- Parameters:
target
- the memory access var handle to be adaptedadaptedType
- the adapted type- Returns:
- the adapted var handle.
- Throws:
IllegalArgumentException
- if the carrier type oftarget
is not one ofbyte
,short
, orint
; ifadaptedType
is not one ofint
, orlong
; if the bitwidth of theadaptedType
is not greater than that of thetarget
carrier type.- See Java Language Specification:
-
5.1.3 Narrowing Primitive Conversion
-
filterValue
public static VarHandle filterValue(VarHandle target, MethodHandle filterToTarget, MethodHandle filterFromTarget)Adapts a target var handle by pre-processing incoming and outgoing values using a pair of filter functions.When calling e.g.
VarHandle.set(Object...)
on the resulting var handle, the incoming value (of typeT
, whereT
is the last parameter type of the first filter function) is processed using the first filter and then passed to the target var handle. Conversely, when calling e.g.VarHandle.get(Object...)
on the resulting var handle, the return value obtained from the target var handle (of typeT
, whereT
is the last parameter type of the second filter function) is processed using the second filter and returned to the caller. More advanced access mode types, such asVarHandle.AccessMode.COMPARE_AND_EXCHANGE
might apply both filters at the same time.For the boxing and unboxing filters to be well formed, their types must be of the form
(A... , S) -> T
and(A... , T) -> S
, respectively, whereT
is the type of the target var handle. If this is the case, the resulting var handle will have typeS
and will feature the additional coordinatesA...
(which will be appended to the coordinates of the target var handle).The resulting var handle will feature the same access modes (see
VarHandle.AccessMode
and atomic access guarantees as those featured by the target var handle.- Parameters:
target
- the target var handlefilterToTarget
- a filter to convert some typeS
into the type oftarget
filterFromTarget
- a filter to convert the type oftarget
to some typeS
- Returns:
- an adapter var handle which accepts a new type, performing the provided boxing/unboxing conversions.
- Throws:
IllegalArgumentException
- iffilterFromTarget
andfilterToTarget
are not well-formed, that is, they have types other than(A... , S) -> T
and(A... , T) -> S
, respectively, whereT
is the type of the target var handle, or if eitherfilterFromTarget
orfilterToTarget
throws any checked exceptions.
-
filterCoordinates
Adapts a target var handle by pre-processing incoming coordinate values using unary filter functions.When calling e.g.
VarHandle.get(Object...)
on the resulting var handle, the incoming coordinate values starting at positionpos
(of typeC1, C2 ... Cn
, whereC1, C2 ... Cn
are the return type of the unary filter functions) are transformed into new values (of typeS1, S2 ... Sn
, whereS1, S2 ... Sn
are the parameter types of the unary filter functions), and then passed (along with any coordinate that was left unaltered by the adaptation) to the target var handle.For the coordinate filters to be well formed, their types must be of the form
S1 -> T1, S2 -> T1 ... Sn -> Tn
, whereT1, T2 ... Tn
are the coordinate types starting at positionpos
of the target var handle.The resulting var handle will feature the same access modes (see
VarHandle.AccessMode
) and atomic access guarantees as those featured by the target var handle.- Parameters:
target
- the target var handlepos
- the position of the first coordinate to be transformedfilters
- the unary functions which are used to transform coordinates starting at positionpos
- Returns:
- an adapter var handle which accepts new coordinate types, applying the provided transformation to the new coordinate values.
- Throws:
IllegalArgumentException
- if the handles infilters
are not well-formed, that is, they have types other thanS1 -> T1, S2 -> T2, ... Sn -> Tn
whereT1, T2 ... Tn
are the coordinate types starting at positionpos
of the target var handle, ifpos
is not between 0 and the target var handle coordinate arity, inclusive, or if more filters are provided than the actual number of coordinate types available starting atpos
, or if any of the filters throws any checked exceptions.
-
insertCoordinates
Provides a target var handle with one or more bound coordinates in advance of the var handle's invocation. As a consequence, the resulting var handle will feature less coordinate types than the target var handle.When calling e.g.
VarHandle.get(Object...)
on the resulting var handle, incoming coordinate values are joined with bound coordinate values, and then passed to the target var handle.For the bound coordinates to be well formed, their types must be
T1, T2 ... Tn
, whereT1, T2 ... Tn
are the coordinate types starting at positionpos
of the target var handle.The resulting var handle will feature the same access modes (see
VarHandle.AccessMode
) and atomic access guarantees as those featured by the target var handle.- Parameters:
target
- the var handle to invoke after the bound coordinates are insertedpos
- the position of the first coordinate to be insertedvalues
- the series of bound coordinates to insert- Returns:
- an adapter var handle which inserts an additional coordinates, before calling the target var handle
- Throws:
IllegalArgumentException
- ifpos
is not between 0 and the target var handle coordinate arity, inclusive, or if more values are provided than the actual number of coordinate types available starting atpos
.ClassCastException
- if the bound coordinates invalues
are not well-formed, that is, they have types other thanT1, T2 ... Tn
, whereT1, T2 ... Tn
are the coordinate types starting at positionpos
of the target var handle.
-
permuteCoordinates
public static VarHandle permuteCoordinates(VarHandle target, List<Class<?>> newCoordinates, int... reorder)Provides a var handle which adapts the coordinate values of the target var handle, by re-arranging them so that the new coordinates match the provided ones.The given array controls the reordering. Call
#I
the number of incoming coordinates (the valuenewCoordinates.size()
, and call#O
the number of outgoing coordinates (the number of coordinates associated with the target var handle). Then the length of the reordering array must be#O
, and each element must be a non-negative number less than#I
. For everyN
less than#O
, theN
-th outgoing coordinate will be taken from theI
-th incoming coordinate, whereI
isreorder[N]
.No coordinate value conversions are applied. The type of each incoming coordinate, as determined by
newCoordinates
, must be identical to the type of the corresponding outgoing coordinate in the target var handle.The reordering array need not specify an actual permutation. An incoming coordinate will be duplicated if its index appears more than once in the array, and an incoming coordinate will be dropped if its index does not appear in the array.
The resulting var handle will feature the same access modes (see
VarHandle.AccessMode
) and atomic access guarantees as those featured by the target var handle.- Parameters:
target
- the var handle to invoke after the coordinates have been reorderednewCoordinates
- the new coordinate typesreorder
- an index array which controls the reordering- Returns:
- an adapter var handle which re-arranges the incoming coordinate values, before calling the target var handle
- Throws:
IllegalArgumentException
- if the index array length is not equal to the number of coordinates of the target var handle, or if any index array element is not a valid index for a coordinate ofnewCoordinates
, or if two corresponding coordinate types in the target var handle and innewCoordinates
are not identical.
-
collectCoordinates
Adapts a target var handle handle by pre-processing a sub-sequence of its coordinate values with a filter (a method handle). The pre-processed coordinates are replaced by the result (if any) of the filter function and the target var handle is then called on the modified (usually shortened) coordinate list.If
R
is the return type of the filter (which cannot be void), the target var handle must accept a value of typeR
as its coordinate in positionpos
, preceded and/or followed by any coordinate not passed to the filter. No coordinates are reordered, and the result returned from the filter replaces (in order) the whole subsequence of coordinates originally passed to the adapter.The argument types (if any) of the filter replace zero or one coordinate types of the target var handle, at position
pos
, in the resulting adapted var handle. The return type of the filter must be identical to the coordinate type of the target var handle at positionpos
, and that target var handle coordinate is supplied by the return value of the filter.The resulting var handle will feature the same access modes (see
VarHandle.AccessMode
) and atomic access guarantees as those featured by the target var handle.- Parameters:
target
- the var handle to invoke after the coordinates have been filteredpos
- the position of the coordinate to be filteredfilter
- the filter method handle- Returns:
- an adapter var handle which filters the incoming coordinate values, before calling the target var handle
- Throws:
IllegalArgumentException
- if the return type offilter
is void, or it is not the same as thepos
coordinate of the target var handle, ifpos
is not between 0 and the target var handle coordinate arity, inclusive, if the resulting var handle's type would have too many coordinates, or iffilter
throws any checked exceptions.
-
dropCoordinates
Returns a var handle which will discard some dummy coordinates before delegating to the target var handle. As a consequence, the resulting var handle will feature more coordinate types than the target var handle.The
pos
argument may range between zero and N, where N is the arity of the target var handle's coordinate types. Ifpos
is zero, the dummy coordinates will precede the target's real arguments; ifpos
is N they will come after.The resulting var handle will feature the same access modes (see
VarHandle.AccessMode
) and atomic access guarantees as those featured by the target var handle.- Parameters:
target
- the var handle to invoke after the dummy coordinates are droppedpos
- position of first coordinate to drop (zero for the leftmost)valueTypes
- the type(s) of the coordinate(s) to drop- Returns:
- an adapter var handle which drops some dummy coordinates, before calling the target var handle
- Throws:
IllegalArgumentException
- ifpos
is not between 0 and the target var handle coordinate arity, inclusive.
-