< prev index next >

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

Print this page

        

@@ -34,13 +34,19 @@
 
     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
+                if (f.isFlattened()) {
+                    return f.isFinal() && !isWriteAllowedOnFinalFields
+                        ? new VarHandleValues.FieldInstanceReadOnly(refc, foffset, type)
+                        : new VarHandleValues.FieldInstanceReadWrite(refc, foffset, type);
+                } else {
+                    return f.isFinal() && !isWriteAllowedOnFinalFields
                        ? new VarHandleReferences.FieldInstanceReadOnly(refc, foffset, type)
                        : new VarHandleReferences.FieldInstanceReadWrite(refc, foffset, type);
+                }
             }
             else if (type == boolean.class) {
                 return f.isFinal() && !isWriteAllowedOnFinalFields
                        ? new VarHandleBooleans.FieldInstanceReadOnly(refc, foffset)
                        : new VarHandleBooleans.FieldInstanceReadWrite(refc, foffset);

@@ -95,13 +101,19 @@
                 UNSAFE.ensureClassInitialized(refc);
 
             Object base = MethodHandleNatives.staticFieldBase(f);
             long foffset = MethodHandleNatives.staticFieldOffset(f);
             if (!type.isPrimitive()) {
-                return f.isFinal() && !isWriteAllowedOnFinalFields
-                       ? new VarHandleReferences.FieldStaticReadOnly(base, foffset, type)
-                       : new VarHandleReferences.FieldStaticReadWrite(base, foffset, type);
+                if (f.isFlattened()) {
+                    return f.isFinal() && !isWriteAllowedOnFinalFields
+                            ? new VarHandleValues.FieldStaticReadOnly(refc, foffset, type)
+                            : new VarHandleValues.FieldStaticReadWrite(refc, foffset, type);
+                } else {
+                    return f.isFinal() && !isWriteAllowedOnFinalFields
+                            ? new VarHandleReferences.FieldStaticReadOnly(base, foffset, type)
+                            : new VarHandleReferences.FieldStaticReadWrite(base, foffset, type);
+                }
             }
             else if (type == boolean.class) {
                 return f.isFinal() && !isWriteAllowedOnFinalFields
                        ? new VarHandleBooleans.FieldStaticReadOnly(base, foffset)
                        : new VarHandleBooleans.FieldStaticReadWrite(base, foffset);

@@ -188,11 +200,17 @@
         int aoffset = UNSAFE.arrayBaseOffset(arrayClass);
         int ascale = UNSAFE.arrayIndexScale(arrayClass);
         int ashift = 31 - Integer.numberOfLeadingZeros(ascale);
 
         if (!componentType.isPrimitive()) {
-            return new VarHandleReferences.Array(aoffset, ashift, arrayClass);
+            // the redundant componentType.isValue() check is there to
+            // minimize the performance impact to non-value array.
+            // It should be removed when Unsafe::isFlattenedArray is intrinsified.
+
+            return componentType.isInlineClass() && UNSAFE.isFlattenedArray(arrayClass)
+                ? new VarHandleValues.Array(aoffset, ashift, arrayClass)
+                : new VarHandleReferences.Array(aoffset, ashift, arrayClass);
         }
         else if (componentType == boolean.class) {
             return new VarHandleBooleans.Array(aoffset, ashift);
         }
         else if (componentType == byte.class) {
< prev index next >