< prev index next >

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

Print this page
@@ -29,26 +29,22 @@
  
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Field;
  import java.lang.reflect.Method;
  import java.lang.reflect.Modifier;
- import java.lang.reflect.Parameter;
  import java.nio.ByteOrder;
  import java.util.ArrayList;
- import java.util.LinkedHashMap;
  import java.util.List;
- import java.util.Map;
  import java.util.Objects;
  import java.util.concurrent.ConcurrentHashMap;
  import java.util.concurrent.ConcurrentMap;
  import java.util.stream.Stream;
  
  import static java.lang.invoke.MethodHandleStatics.UNSAFE;
  import static java.lang.invoke.MethodHandleStatics.VAR_HANDLE_IDENTITY_ADAPT;
  import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
  import static java.util.stream.Collectors.joining;
- import static java.util.stream.Collectors.toList;
  
  final class VarHandles {
  
      static ClassValue<ConcurrentMap<Integer, MethodHandle>> ADDRESS_FACTORIES = new ClassValue<>() {
          @Override

@@ -59,13 +55,19 @@
  
      static VarHandle makeFieldHandle(MemberName f, Class<?> refc, Class<?> type, boolean isWriteAllowedOnFinalFields) {
          if (!f.isStatic()) {
              long foffset = MethodHandleNatives.objectFieldOffset(f);
              if (!type.isPrimitive()) {
-                 return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
+                 if (f.isFlattened()) {
+                     return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
+                         ? new VarHandleValues.FieldInstanceReadOnly(refc, foffset, type)
+                         : new VarHandleValues.FieldInstanceReadWrite(refc, foffset, type));
+                 } else {
+                     return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
                         ? new VarHandleReferences.FieldInstanceReadOnly(refc, foffset, type)
                         : new VarHandleReferences.FieldInstanceReadWrite(refc, foffset, type));
+                 }
              }
              else if (type == boolean.class) {
                  return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
                         ? new VarHandleBooleans.FieldInstanceReadOnly(refc, foffset)
                         : new VarHandleBooleans.FieldInstanceReadWrite(refc, foffset));

@@ -120,13 +122,19 @@
                  UNSAFE.ensureClassInitialized(refc);
  
              Object base = MethodHandleNatives.staticFieldBase(f);
              long foffset = MethodHandleNatives.staticFieldOffset(f);
              if (!type.isPrimitive()) {
-                 return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
-                        ? new VarHandleReferences.FieldStaticReadOnly(base, foffset, type)
-                        : new VarHandleReferences.FieldStaticReadWrite(base, foffset, type));
+                 if (f.isFlattened()) {
+                     return maybeAdapt(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 maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
                         ? new VarHandleBooleans.FieldStaticReadOnly(base, foffset)
                         : new VarHandleBooleans.FieldStaticReadWrite(base, foffset));

@@ -213,11 +221,17 @@
          int aoffset = UNSAFE.arrayBaseOffset(arrayClass);
          int ascale = UNSAFE.arrayIndexScale(arrayClass);
          int ashift = 31 - Integer.numberOfLeadingZeros(ascale);
  
          if (!componentType.isPrimitive()) {
-             return maybeAdapt(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 maybeAdapt(componentType.isValueType() && UNSAFE.isFlattenedArray(arrayClass)
+                 ? new VarHandleValues.Array(aoffset, ashift, arrayClass)
+                 : new VarHandleReferences.Array(aoffset, ashift, arrayClass));
          }
          else if (componentType == boolean.class) {
              return maybeAdapt(new VarHandleBooleans.Array(aoffset, ashift));
          }
          else if (componentType == byte.class) {

@@ -615,11 +629,11 @@
              if (MethodHandleNatives.refKindIsMethod(refKind)) {
                  exceptionTypes = info.reflectAs(Method.class, MethodHandles.Lookup.IMPL_LOOKUP)
                          .getExceptionTypes();
              } else if (MethodHandleNatives.refKindIsField(refKind)) {
                  exceptionTypes = null;
-             } else if (MethodHandleNatives.refKindIsConstructor(refKind)) {
+             } else if (MethodHandleNatives.refKindIsObjectConstructor(refKind)) {
                  exceptionTypes = info.reflectAs(Constructor.class, MethodHandles.Lookup.IMPL_LOOKUP)
                          .getExceptionTypes();
              } else {
                  throw new AssertionError("Cannot get here");
              }
< prev index next >