--- old/src/java.base/share/classes/java/lang/invoke/VarHandles.java 2019-12-09 18:15:04.443544426 +0000 +++ new/src/java.base/share/classes/java/lang/invoke/VarHandles.java 2019-12-09 18:15:03.975536146 +0000 @@ -25,13 +25,26 @@ 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> ADDRESS_FACTORIES = new ClassValue<>() { + @Override + protected ConcurrentMap 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); @@ -279,6 +292,43 @@ 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 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