< prev index next >

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

Print this page

        

@@ -23,17 +23,31 @@
  * questions.
  */
 
 package java.lang.invoke;
 
+import jdk.internal.foreign.LayoutPathsImpl;
+
+import java.foreign.layout.Layout;
+import java.foreign.layout.LayoutPath;
+import java.foreign.layout.Value;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
 
 final class VarHandles {
 
+    static ClassValue<Map<Integer, MethodHandle>> addressFactories = new ClassValue<Map<Integer, MethodHandle>>() {
+        @Override
+        protected Map<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,10 +291,40 @@
         }
 
         throw new UnsupportedOperationException();
     }
 
+    static VarHandle makeMemoryAddressViewHandle(Class<?> carrier, LayoutPath path) {
+        if (carrier.isArray())
+            throw new IllegalArgumentException("Illegal array carrier: " + carrier);
+
+        Layout layout = path.layout();
+
+        if (!(layout instanceof Value)) {
+            throw new IllegalArgumentException("Not a value layout: " + layout);
+        }
+
+        long offset = path.offset() / 8;
+        long length = layout.bitsSize() / 8;
+        boolean be = ((Value)layout).endianness() == Value.Endianness.BIG_ENDIAN;
+
+        long[] strides = ((LayoutPathsImpl.LayoutPathImpl)path).enclosingSequences().stream()
+                .mapToLong(seq -> seq.element().bitsSize() / 8)
+                .toArray();
+
+        Map<Integer, MethodHandle> carrierFactory = addressFactories.get(carrier);
+        MethodHandle fac = carrierFactory.computeIfAbsent(strides.length,
+                dims -> new AddressVarHandleGenerator(carrier, dims)
+                            .generateHandleFactory());
+        
+        try {
+            return (VarHandle)fac.invoke(be, length, offset, 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 >