< prev index next >

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

Print this page
rev 55127 : 8223351: [lworld] Primary mirror and nullable mirror for inline type
Reviewed-by: tbd


  26 package java.lang.invoke;
  27 
  28 import java.lang.reflect.Field;
  29 import java.lang.reflect.Modifier;
  30 
  31 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
  32 
  33 final class VarHandles {
  34 
  35     static VarHandle makeFieldHandle(MemberName f, Class<?> refc, Class<?> type, boolean isWriteAllowedOnFinalFields) {
  36         if (!f.isStatic()) {
  37             long foffset = MethodHandleNatives.objectFieldOffset(f);
  38             if (!type.isPrimitive()) {
  39                 if (f.isFlattened()) {
  40                     return f.isFinal() && !isWriteAllowedOnFinalFields
  41                         ? new VarHandleReferences.FlatValueFieldInstanceReadOnly(refc, foffset, type)
  42                         : new VarHandleReferences.FlatValueFieldInstanceReadWrite(refc, foffset, type);
  43                 } else {
  44                     return f.isFinal() && !isWriteAllowedOnFinalFields
  45                        ? new VarHandleReferences.FieldInstanceReadOnly(refc, foffset, type)
  46                        : new VarHandleReferences.FieldInstanceReadWrite(refc, foffset, type, f.isValue());
  47                 }
  48             }
  49             else if (type == boolean.class) {
  50                 return f.isFinal() && !isWriteAllowedOnFinalFields
  51                        ? new VarHandleBooleans.FieldInstanceReadOnly(refc, foffset)
  52                        : new VarHandleBooleans.FieldInstanceReadWrite(refc, foffset);
  53             }
  54             else if (type == byte.class) {
  55                 return f.isFinal() && !isWriteAllowedOnFinalFields
  56                        ? new VarHandleBytes.FieldInstanceReadOnly(refc, foffset)
  57                        : new VarHandleBytes.FieldInstanceReadWrite(refc, foffset);
  58             }
  59             else if (type == short.class) {
  60                 return f.isFinal() && !isWriteAllowedOnFinalFields
  61                        ? new VarHandleShorts.FieldInstanceReadOnly(refc, foffset)
  62                        : new VarHandleShorts.FieldInstanceReadWrite(refc, foffset);
  63             }
  64             else if (type == char.class) {
  65                 return f.isFinal() && !isWriteAllowedOnFinalFields
  66                        ? new VarHandleChars.FieldInstanceReadOnly(refc, foffset)


  89             else {
  90                 throw new UnsupportedOperationException();
  91             }
  92         }
  93         else {
  94             // TODO This is not lazy on first invocation
  95             // and might cause some circular initialization issues
  96 
  97             // Replace with something similar to direct method handles
  98             // where a barrier is used then elided after use
  99 
 100             if (UNSAFE.shouldBeInitialized(refc))
 101                 UNSAFE.ensureClassInitialized(refc);
 102 
 103             Object base = MethodHandleNatives.staticFieldBase(f);
 104             long foffset = MethodHandleNatives.staticFieldOffset(f);
 105             if (!type.isPrimitive()) {
 106                 assert(!f.isFlattened());   // static field is not flattened
 107                 return f.isFinal() && !isWriteAllowedOnFinalFields
 108                        ? new VarHandleReferences.FieldStaticReadOnly(base, foffset, type)
 109                        : new VarHandleReferences.FieldStaticReadWrite(base, foffset, type, f.isValue());
 110             }
 111             else if (type == boolean.class) {
 112                 return f.isFinal() && !isWriteAllowedOnFinalFields
 113                        ? new VarHandleBooleans.FieldStaticReadOnly(base, foffset)
 114                        : new VarHandleBooleans.FieldStaticReadWrite(base, foffset);
 115             }
 116             else if (type == byte.class) {
 117                 return f.isFinal() && !isWriteAllowedOnFinalFields
 118                        ? new VarHandleBytes.FieldStaticReadOnly(base, foffset)
 119                        : new VarHandleBytes.FieldStaticReadWrite(base, foffset);
 120             }
 121             else if (type == short.class) {
 122                 return f.isFinal() && !isWriteAllowedOnFinalFields
 123                        ? new VarHandleShorts.FieldStaticReadOnly(base, foffset)
 124                        : new VarHandleShorts.FieldStaticReadWrite(base, foffset);
 125             }
 126             else if (type == char.class) {
 127                 return f.isFinal() && !isWriteAllowedOnFinalFields
 128                        ? new VarHandleChars.FieldStaticReadOnly(base, foffset)
 129                        : new VarHandleChars.FieldStaticReadWrite(base, foffset);


 183                 return f;
 184             }
 185         }
 186         throw new InternalError("Static field not found at offset");
 187     }
 188 
 189     static VarHandle makeArrayElementHandle(Class<?> arrayClass) {
 190         if (!arrayClass.isArray())
 191             throw new IllegalArgumentException("not an array: " + arrayClass);
 192 
 193         Class<?> componentType = arrayClass.getComponentType();
 194 
 195         int aoffset = UNSAFE.arrayBaseOffset(arrayClass);
 196         int ascale = UNSAFE.arrayIndexScale(arrayClass);
 197         int ashift = 31 - Integer.numberOfLeadingZeros(ascale);
 198 
 199         if (!componentType.isPrimitive()) {
 200             // the redundant componentType.isValue() check is there to
 201             // minimize the performance impact to non-value array.
 202             // It should be removed when Unsafe::isFlattenedArray is intrinsified.
 203             return componentType.isValue() && UNSAFE.isFlattenedArray(arrayClass)
 204                 ? new VarHandleReferences.ValueArray(aoffset, ashift, arrayClass)
 205                 : new VarHandleReferences.Array(aoffset, ashift, arrayClass);
 206         }
 207         else if (componentType == boolean.class) {
 208             return new VarHandleBooleans.Array(aoffset, ashift);
 209         }
 210         else if (componentType == byte.class) {
 211             return new VarHandleBytes.Array(aoffset, ashift);
 212         }
 213         else if (componentType == short.class) {
 214             return new VarHandleShorts.Array(aoffset, ashift);
 215         }
 216         else if (componentType == char.class) {
 217             return new VarHandleChars.Array(aoffset, ashift);
 218         }
 219         else if (componentType == int.class) {
 220             return new VarHandleInts.Array(aoffset, ashift);
 221         }
 222         else if (componentType == long.class) {
 223             return new VarHandleLongs.Array(aoffset, ashift);




  26 package java.lang.invoke;
  27 
  28 import java.lang.reflect.Field;
  29 import java.lang.reflect.Modifier;
  30 
  31 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
  32 
  33 final class VarHandles {
  34 
  35     static VarHandle makeFieldHandle(MemberName f, Class<?> refc, Class<?> type, boolean isWriteAllowedOnFinalFields) {
  36         if (!f.isStatic()) {
  37             long foffset = MethodHandleNatives.objectFieldOffset(f);
  38             if (!type.isPrimitive()) {
  39                 if (f.isFlattened()) {
  40                     return f.isFinal() && !isWriteAllowedOnFinalFields
  41                         ? new VarHandleReferences.FlatValueFieldInstanceReadOnly(refc, foffset, type)
  42                         : new VarHandleReferences.FlatValueFieldInstanceReadWrite(refc, foffset, type);
  43                 } else {
  44                     return f.isFinal() && !isWriteAllowedOnFinalFields
  45                        ? new VarHandleReferences.FieldInstanceReadOnly(refc, foffset, type)
  46                        : new VarHandleReferences.FieldInstanceReadWrite(refc, foffset, type, f.isInlineableField());
  47                 }
  48             }
  49             else if (type == boolean.class) {
  50                 return f.isFinal() && !isWriteAllowedOnFinalFields
  51                        ? new VarHandleBooleans.FieldInstanceReadOnly(refc, foffset)
  52                        : new VarHandleBooleans.FieldInstanceReadWrite(refc, foffset);
  53             }
  54             else if (type == byte.class) {
  55                 return f.isFinal() && !isWriteAllowedOnFinalFields
  56                        ? new VarHandleBytes.FieldInstanceReadOnly(refc, foffset)
  57                        : new VarHandleBytes.FieldInstanceReadWrite(refc, foffset);
  58             }
  59             else if (type == short.class) {
  60                 return f.isFinal() && !isWriteAllowedOnFinalFields
  61                        ? new VarHandleShorts.FieldInstanceReadOnly(refc, foffset)
  62                        : new VarHandleShorts.FieldInstanceReadWrite(refc, foffset);
  63             }
  64             else if (type == char.class) {
  65                 return f.isFinal() && !isWriteAllowedOnFinalFields
  66                        ? new VarHandleChars.FieldInstanceReadOnly(refc, foffset)


  89             else {
  90                 throw new UnsupportedOperationException();
  91             }
  92         }
  93         else {
  94             // TODO This is not lazy on first invocation
  95             // and might cause some circular initialization issues
  96 
  97             // Replace with something similar to direct method handles
  98             // where a barrier is used then elided after use
  99 
 100             if (UNSAFE.shouldBeInitialized(refc))
 101                 UNSAFE.ensureClassInitialized(refc);
 102 
 103             Object base = MethodHandleNatives.staticFieldBase(f);
 104             long foffset = MethodHandleNatives.staticFieldOffset(f);
 105             if (!type.isPrimitive()) {
 106                 assert(!f.isFlattened());   // static field is not flattened
 107                 return f.isFinal() && !isWriteAllowedOnFinalFields
 108                        ? new VarHandleReferences.FieldStaticReadOnly(base, foffset, type)
 109                        : new VarHandleReferences.FieldStaticReadWrite(base, foffset, type, f.isInlineableField());
 110             }
 111             else if (type == boolean.class) {
 112                 return f.isFinal() && !isWriteAllowedOnFinalFields
 113                        ? new VarHandleBooleans.FieldStaticReadOnly(base, foffset)
 114                        : new VarHandleBooleans.FieldStaticReadWrite(base, foffset);
 115             }
 116             else if (type == byte.class) {
 117                 return f.isFinal() && !isWriteAllowedOnFinalFields
 118                        ? new VarHandleBytes.FieldStaticReadOnly(base, foffset)
 119                        : new VarHandleBytes.FieldStaticReadWrite(base, foffset);
 120             }
 121             else if (type == short.class) {
 122                 return f.isFinal() && !isWriteAllowedOnFinalFields
 123                        ? new VarHandleShorts.FieldStaticReadOnly(base, foffset)
 124                        : new VarHandleShorts.FieldStaticReadWrite(base, foffset);
 125             }
 126             else if (type == char.class) {
 127                 return f.isFinal() && !isWriteAllowedOnFinalFields
 128                        ? new VarHandleChars.FieldStaticReadOnly(base, foffset)
 129                        : new VarHandleChars.FieldStaticReadWrite(base, foffset);


 183                 return f;
 184             }
 185         }
 186         throw new InternalError("Static field not found at offset");
 187     }
 188 
 189     static VarHandle makeArrayElementHandle(Class<?> arrayClass) {
 190         if (!arrayClass.isArray())
 191             throw new IllegalArgumentException("not an array: " + arrayClass);
 192 
 193         Class<?> componentType = arrayClass.getComponentType();
 194 
 195         int aoffset = UNSAFE.arrayBaseOffset(arrayClass);
 196         int ascale = UNSAFE.arrayIndexScale(arrayClass);
 197         int ashift = 31 - Integer.numberOfLeadingZeros(ascale);
 198 
 199         if (!componentType.isPrimitive()) {
 200             // the redundant componentType.isValue() check is there to
 201             // minimize the performance impact to non-value array.
 202             // It should be removed when Unsafe::isFlattenedArray is intrinsified.
 203             return componentType.isInlineClass() && UNSAFE.isFlattenedArray(arrayClass)
 204                 ? new VarHandleReferences.ValueArray(aoffset, ashift, arrayClass)
 205                 : new VarHandleReferences.Array(aoffset, ashift, arrayClass);
 206         }
 207         else if (componentType == boolean.class) {
 208             return new VarHandleBooleans.Array(aoffset, ashift);
 209         }
 210         else if (componentType == byte.class) {
 211             return new VarHandleBytes.Array(aoffset, ashift);
 212         }
 213         else if (componentType == short.class) {
 214             return new VarHandleShorts.Array(aoffset, ashift);
 215         }
 216         else if (componentType == char.class) {
 217             return new VarHandleChars.Array(aoffset, ashift);
 218         }
 219         else if (componentType == int.class) {
 220             return new VarHandleInts.Array(aoffset, ashift);
 221         }
 222         else if (componentType == long.class) {
 223             return new VarHandleLongs.Array(aoffset, ashift);


< prev index next >