< prev index next >

src/java.base/share/classes/java/lang/invoke/VarHandles.java

Print this page

        

*** 23,39 **** --- 23,52 ---- * questions. */ package java.lang.invoke; + import sun.invoke.util.Wrapper; + import java.lang.reflect.Field; import java.lang.reflect.Modifier; + import java.nio.ByteOrder; + import java.util.Map; + import java.util.concurrent.ConcurrentHashMap; + import java.util.concurrent.ConcurrentMap; import static java.lang.invoke.MethodHandleStatics.UNSAFE; final class VarHandles { + static ClassValue<ConcurrentMap<Integer, MethodHandle>> ADDRESS_FACTORIES = new ClassValue<>() { + @Override + protected ConcurrentMap<Integer, MethodHandle> computeValue(Class<?> type) { + return new ConcurrentHashMap<>(); + } + }; + static VarHandle makeFieldHandle(MemberName f, Class<?> refc, Class<?> type, boolean isWriteAllowedOnFinalFields) { if (!f.isStatic()) { long foffset = MethodHandleNatives.objectFieldOffset(f); if (!type.isPrimitive()) { return f.isFinal() && !isWriteAllowedOnFinalFields
*** 277,286 **** --- 290,336 ---- } throw new UnsupportedOperationException(); } + /** + * Creates a memory access VarHandle. + * + * Resulting VarHandle will take a memory address as first argument, + * and a certain number of coordinate {@code long} parameters, depending on the length + * of the {@code strides} argument array. + * + * Coordinates are multiplied with corresponding scale factors ({@code strides}) and added + * to a single fixed offset to compute an effective offset from the given MemoryAddress for the access. + * + * @param carrier the Java carrier type. + * @param alignmentMask alignment requirement to be checked upon access. In bytes. Expressed as a mask. + * @param byteOrder the byte order. + * @param offset a constant offset for the access. + * @param strides the scale factors with which to multiply given access coordinates. + * @return the created VarHandle. + */ + static VarHandle makeMemoryAddressViewHandle(Class<?> carrier, long alignmentMask, + ByteOrder byteOrder, long offset, long[] strides) { + if (!carrier.isPrimitive() || carrier == void.class || carrier == boolean.class) { + throw new IllegalArgumentException("Invalid carrier: " + carrier.getName()); + } + long size = Wrapper.forPrimitiveType(carrier).bitWidth() / 8; + boolean be = byteOrder == ByteOrder.BIG_ENDIAN; + + Map<Integer, MethodHandle> carrierFactory = ADDRESS_FACTORIES.get(carrier); + MethodHandle fac = carrierFactory.computeIfAbsent(strides.length, + dims -> new AddressVarHandleGenerator(carrier, dims) + .generateHandleFactory()); + + try { + return (VarHandle)fac.invoke(be, size, offset, alignmentMask, strides); + } catch (Throwable ex) { + throw new IllegalStateException(ex); + } + } + // /** // * A helper program to generate the VarHandleGuards class with a set of // * static guard methods each of which corresponds to a particular shape and // * performs a type check of the symbolic type descriptor with the VarHandle // * type descriptor before linking/invoking to the underlying operation as
< prev index next >