< prev index next > src/java.base/share/classes/java/lang/invoke/MethodHandles.java
Print this page
}
return expectedType;
}
- /**
- * Creates a var handle object, which can be used to dereference a {@linkplain java.lang.foreign.MemorySegment memory segment}
- * at a given byte offset, using the provided value layout.
- *
- * <p>The provided layout specifies the {@linkplain ValueLayout#carrier() carrier type},
- * the {@linkplain ValueLayout#byteSize() byte size},
- * the {@linkplain ValueLayout#byteAlignment() byte alignment} and the {@linkplain ValueLayout#order() byte order}
- * associated with the returned var handle.
- *
- * <p>The list of coordinate types associated with the returned var handle is {@code (MemorySegment, long)},
- * where the {@code long} coordinate type corresponds to byte offset into the given memory segment coordinate.
- * Thus, the returned var handle accesses bytes at an offset in a given memory segment, composing bytes to or from
- * a value of the var handle type. Moreover, the access operation will honor the endianness and the
- * alignment constraints expressed in the provided layout.
- *
- * <p>As an example, consider the memory layout expressed by a {@link GroupLayout} instance constructed as follows:
- * {@snippet lang="java" :
- * GroupLayout seq = java.lang.foreign.MemoryLayout.structLayout(
- * MemoryLayout.paddingLayout(4),
- * ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN).withName("value")
- * );
- * }
- * To access the member layout named {@code value}, we can construct a memory segment view var handle as follows:
- * {@snippet lang="java" :
- * VarHandle handle = MethodHandles.memorySegmentViewVarHandle(ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN)); //(MemorySegment, long) -> int
- * handle = MethodHandles.insertCoordinates(handle, 1, 4); //(MemorySegment) -> int
- * }
- *
- * @apiNote The resulting var handle features certain <i>access mode restrictions</i>,
- * which are common to all memory segment view var handles. A memory segment view var handle is associated
- * with an access size {@code S} and an alignment constraint {@code B}
- * (both expressed in bytes). We say that a memory access operation is <em>fully aligned</em> if it occurs
- * at a memory address {@code A} which is compatible with both alignment constraints {@code S} and {@code B}.
- * If access is fully aligned then following access modes are supported and are
- * guaranteed to support atomic access:
- * <ul>
- * <li>read write access modes for all {@code T}, with the exception of
- * access modes {@code get} and {@code set} for {@code long} and
- * {@code double} on 32-bit platforms.
- * <li>atomic update access modes for {@code int}, {@code long},
- * {@code float}, {@code double} or {@link MemorySegment}.
- * (Future major platform releases of the JDK may support additional
- * types for certain currently unsupported access modes.)
- * <li>numeric atomic update access modes for {@code int}, {@code long} and {@link MemorySegment}.
- * (Future major platform releases of the JDK may support additional
- * numeric types for certain currently unsupported access modes.)
- * <li>bitwise atomic update access modes for {@code int}, {@code long} and {@link MemorySegment}.
- * (Future major platform releases of the JDK may support additional
- * numeric types for certain currently unsupported access modes.)
- * </ul>
- *
- * If {@code T} is {@code float}, {@code double} or {@link MemorySegment} then atomic
- * update access modes compare values using their bitwise representation
- * (see {@link Float#floatToRawIntBits},
- * {@link Double#doubleToRawLongBits} and {@link MemorySegment#address()}, respectively).
- * <p>
- * Alternatively, a memory access operation is <em>partially aligned</em> if it occurs at a memory address {@code A}
- * which is only compatible with the alignment constraint {@code B}; in such cases, access for anything other than the
- * {@code get} and {@code set} access modes will result in an {@code IllegalStateException}. If access is partially aligned,
- * atomic access is only guaranteed with respect to the largest power of two that divides the GCD of {@code A} and {@code S}.
- * <p>
- * In all other cases, we say that a memory access operation is <em>misaligned</em>; in such cases an
- * {@code IllegalStateException} is thrown, irrespective of the access mode being used.
- * <p>
- * Finally, if {@code T} is {@code MemorySegment} all write access modes throw {@link IllegalArgumentException}
- * unless the value to be written is a {@linkplain MemorySegment#isNative() native} memory segment.
- *
- * @param layout the value layout for which a memory access handle is to be obtained.
- * @return the new memory segment view var handle.
- * @throws NullPointerException if {@code layout} is {@code null}.
- * @see MemoryLayout#varHandle(MemoryLayout.PathElement...)
- * @since 19
- */
- @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
- public static VarHandle memorySegmentViewVarHandle(ValueLayout layout) {
- Objects.requireNonNull(layout);
- return Utils.makeSegmentViewVarHandle(layout);
- }
-
/**
* Adapts a target var handle by pre-processing incoming and outgoing values using a pair of filter functions.
* <p>
* When calling e.g. {@link VarHandle#set(Object...)} on the resulting var handle, the incoming value (of type {@code T}, where
* {@code T} is the <em>last</em> parameter type of the first filter function) is processed using the first filter and then passed
* @return an adapter var handle which accepts a new type, performing the provided boxing/unboxing conversions.
* @throws IllegalArgumentException if {@code filterFromTarget} and {@code filterToTarget} are not well-formed, that is, they have types
* other than {@code (A... , S) -> T} and {@code (A... , T) -> S}, respectively, where {@code T} is the type of the target var handle,
* or if it's determined that either {@code filterFromTarget} or {@code filterToTarget} throws any checked exceptions.
* @throws NullPointerException if any of the arguments is {@code null}.
! * @since 19
*/
- @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public static VarHandle filterValue(VarHandle target, MethodHandle filterToTarget, MethodHandle filterFromTarget) {
return VarHandles.filterValue(target, filterToTarget, filterFromTarget);
}
/**
* @return an adapter var handle which accepts a new type, performing the provided boxing/unboxing conversions.
* @throws IllegalArgumentException if {@code filterFromTarget} and {@code filterToTarget} are not well-formed, that is, they have types
* other than {@code (A... , S) -> T} and {@code (A... , T) -> S}, respectively, where {@code T} is the type of the target var handle,
* or if it's determined that either {@code filterFromTarget} or {@code filterToTarget} throws any checked exceptions.
* @throws NullPointerException if any of the arguments is {@code null}.
! * @since 22
*/
public static VarHandle filterValue(VarHandle target, MethodHandle filterToTarget, MethodHandle filterFromTarget) {
return VarHandles.filterValue(target, filterToTarget, filterFromTarget);
}
/**
* other than {@code S1 -> T1, S2 -> T2, ... Sn -> Tn} where {@code T1, T2 ... Tn} are the coordinate types starting
* at position {@code pos} of the target var handle, if {@code pos} 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 at {@code pos},
* or if it's determined that any of the filters throws any checked exceptions.
* @throws NullPointerException if any of the arguments is {@code null} or {@code filters} contains {@code null}.
! * @since 19
*/
- @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public static VarHandle filterCoordinates(VarHandle target, int pos, MethodHandle... filters) {
return VarHandles.filterCoordinates(target, pos, filters);
}
/**
* other than {@code S1 -> T1, S2 -> T2, ... Sn -> Tn} where {@code T1, T2 ... Tn} are the coordinate types starting
* at position {@code pos} of the target var handle, if {@code pos} 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 at {@code pos},
* or if it's determined that any of the filters throws any checked exceptions.
* @throws NullPointerException if any of the arguments is {@code null} or {@code filters} contains {@code null}.
! * @since 22
*/
public static VarHandle filterCoordinates(VarHandle target, int pos, MethodHandle... filters) {
return VarHandles.filterCoordinates(target, pos, filters);
}
/**
* or if more values are provided than the actual number of coordinate types available starting at {@code pos}.
* @throws ClassCastException if the bound coordinates in {@code values} are not well-formed, that is, they have types
* other than {@code T1, T2 ... Tn }, where {@code T1, T2 ... Tn} are the coordinate types starting at position {@code pos}
* of the target var handle.
* @throws NullPointerException if any of the arguments is {@code null} or {@code values} contains {@code null}.
! * @since 19
*/
- @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public static VarHandle insertCoordinates(VarHandle target, int pos, Object... values) {
return VarHandles.insertCoordinates(target, pos, values);
}
/**
* or if more values are provided than the actual number of coordinate types available starting at {@code pos}.
* @throws ClassCastException if the bound coordinates in {@code values} are not well-formed, that is, they have types
* other than {@code T1, T2 ... Tn }, where {@code T1, T2 ... Tn} are the coordinate types starting at position {@code pos}
* of the target var handle.
* @throws NullPointerException if any of the arguments is {@code null} or {@code values} contains {@code null}.
! * @since 22
*/
public static VarHandle insertCoordinates(VarHandle target, int pos, Object... values) {
return VarHandles.insertCoordinates(target, pos, values);
}
/**
* @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 of {@code newCoordinates}, or if two corresponding coordinate types in
* the target var handle and in {@code newCoordinates} are not identical.
* @throws NullPointerException if any of the arguments is {@code null} or {@code newCoordinates} contains {@code null}.
! * @since 19
*/
- @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public static VarHandle permuteCoordinates(VarHandle target, List<Class<?>> newCoordinates, int... reorder) {
return VarHandles.permuteCoordinates(target, newCoordinates, reorder);
}
/**
* @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 of {@code newCoordinates}, or if two corresponding coordinate types in
* the target var handle and in {@code newCoordinates} are not identical.
* @throws NullPointerException if any of the arguments is {@code null} or {@code newCoordinates} contains {@code null}.
! * @since 22
*/
public static VarHandle permuteCoordinates(VarHandle target, List<Class<?>> newCoordinates, int... reorder) {
return VarHandles.permuteCoordinates(target, newCoordinates, reorder);
}
/**
* is not void, and it is not the same as the {@code pos} coordinate of the target var handle,
* if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive,
* if the resulting var handle's type would have <a href="MethodHandle.html#maxarity">too many coordinates</a>,
* or if it's determined that {@code filter} throws any checked exceptions.
* @throws NullPointerException if any of the arguments is {@code null}.
! * @since 19
*/
- @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public static VarHandle collectCoordinates(VarHandle target, int pos, MethodHandle filter) {
return VarHandles.collectCoordinates(target, pos, filter);
}
/**
* is not void, and it is not the same as the {@code pos} coordinate of the target var handle,
* if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive,
* if the resulting var handle's type would have <a href="MethodHandle.html#maxarity">too many coordinates</a>,
* or if it's determined that {@code filter} throws any checked exceptions.
* @throws NullPointerException if any of the arguments is {@code null}.
! * @since 22
*/
public static VarHandle collectCoordinates(VarHandle target, int pos, MethodHandle filter) {
return VarHandles.collectCoordinates(target, pos, filter);
}
/**
* @param valueTypes the type(s) of the coordinate(s) to drop
* @return an adapter var handle which drops some dummy coordinates,
* before calling the target var handle
* @throws IllegalArgumentException if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive.
* @throws NullPointerException if any of the arguments is {@code null} or {@code valueTypes} contains {@code null}.
! * @since 19
*/
- @PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
public static VarHandle dropCoordinates(VarHandle target, int pos, Class<?>... valueTypes) {
return VarHandles.dropCoordinates(target, pos, valueTypes);
}
}
* @param valueTypes the type(s) of the coordinate(s) to drop
* @return an adapter var handle which drops some dummy coordinates,
* before calling the target var handle
* @throws IllegalArgumentException if {@code pos} is not between 0 and the target var handle coordinate arity, inclusive.
* @throws NullPointerException if any of the arguments is {@code null} or {@code valueTypes} contains {@code null}.
! * @since 22
*/
public static VarHandle dropCoordinates(VarHandle target, int pos, Class<?>... valueTypes) {
return VarHandles.dropCoordinates(target, pos, valueTypes);
}
}
< prev index next >