< prev index next >

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

Print this page




  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  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                 return f.isFinal() && !isWriteAllowedOnFinalFields





  40                        ? new VarHandleReferences.FieldInstanceReadOnly(refc, foffset, type)
  41                        : new VarHandleReferences.FieldInstanceReadWrite(refc, foffset, type);

  42             }
  43             else if (type == boolean.class) {
  44                 return f.isFinal() && !isWriteAllowedOnFinalFields
  45                        ? new VarHandleBooleans.FieldInstanceReadOnly(refc, foffset)
  46                        : new VarHandleBooleans.FieldInstanceReadWrite(refc, foffset);
  47             }
  48             else if (type == byte.class) {
  49                 return f.isFinal() && !isWriteAllowedOnFinalFields
  50                        ? new VarHandleBytes.FieldInstanceReadOnly(refc, foffset)
  51                        : new VarHandleBytes.FieldInstanceReadWrite(refc, foffset);
  52             }
  53             else if (type == short.class) {
  54                 return f.isFinal() && !isWriteAllowedOnFinalFields
  55                        ? new VarHandleShorts.FieldInstanceReadOnly(refc, foffset)
  56                        : new VarHandleShorts.FieldInstanceReadWrite(refc, foffset);
  57             }
  58             else if (type == char.class) {
  59                 return f.isFinal() && !isWriteAllowedOnFinalFields
  60                        ? new VarHandleChars.FieldInstanceReadOnly(refc, foffset)
  61                        : new VarHandleChars.FieldInstanceReadWrite(refc, foffset);


  80                        ? new VarHandleDoubles.FieldInstanceReadOnly(refc, foffset)
  81                        : new VarHandleDoubles.FieldInstanceReadWrite(refc, foffset);
  82             }
  83             else {
  84                 throw new UnsupportedOperationException();
  85             }
  86         }
  87         else {
  88             // TODO This is not lazy on first invocation
  89             // and might cause some circular initialization issues
  90 
  91             // Replace with something similar to direct method handles
  92             // where a barrier is used then elided after use
  93 
  94             if (UNSAFE.shouldBeInitialized(refc))
  95                 UNSAFE.ensureClassInitialized(refc);
  96 
  97             Object base = MethodHandleNatives.staticFieldBase(f);
  98             long foffset = MethodHandleNatives.staticFieldOffset(f);
  99             if (!type.isPrimitive()) {
 100                 return f.isFinal() && !isWriteAllowedOnFinalFields
 101                        ? new VarHandleReferences.FieldStaticReadOnly(base, foffset, type)
 102                        : new VarHandleReferences.FieldStaticReadWrite(base, foffset, type);






 103             }
 104             else if (type == boolean.class) {
 105                 return f.isFinal() && !isWriteAllowedOnFinalFields
 106                        ? new VarHandleBooleans.FieldStaticReadOnly(base, foffset)
 107                        : new VarHandleBooleans.FieldStaticReadWrite(base, foffset);
 108             }
 109             else if (type == byte.class) {
 110                 return f.isFinal() && !isWriteAllowedOnFinalFields
 111                        ? new VarHandleBytes.FieldStaticReadOnly(base, foffset)
 112                        : new VarHandleBytes.FieldStaticReadWrite(base, foffset);
 113             }
 114             else if (type == short.class) {
 115                 return f.isFinal() && !isWriteAllowedOnFinalFields
 116                        ? new VarHandleShorts.FieldStaticReadOnly(base, foffset)
 117                        : new VarHandleShorts.FieldStaticReadWrite(base, foffset);
 118             }
 119             else if (type == char.class) {
 120                 return f.isFinal() && !isWriteAllowedOnFinalFields
 121                        ? new VarHandleChars.FieldStaticReadOnly(base, foffset)
 122                        : new VarHandleChars.FieldStaticReadWrite(base, foffset);


 173 
 174             if (offset == UNSAFE.staticFieldOffset(f)) {
 175                 assert f.getType() == fieldType;
 176                 return f;
 177             }
 178         }
 179         throw new InternalError("Static field not found at offset");
 180     }
 181 
 182     static VarHandle makeArrayElementHandle(Class<?> arrayClass) {
 183         if (!arrayClass.isArray())
 184             throw new IllegalArgumentException("not an array: " + arrayClass);
 185 
 186         Class<?> componentType = arrayClass.getComponentType();
 187 
 188         int aoffset = UNSAFE.arrayBaseOffset(arrayClass);
 189         int ascale = UNSAFE.arrayIndexScale(arrayClass);
 190         int ashift = 31 - Integer.numberOfLeadingZeros(ascale);
 191 
 192         if (!componentType.isPrimitive()) {
 193             return new VarHandleReferences.Array(aoffset, ashift, arrayClass);






 194         }
 195         else if (componentType == boolean.class) {
 196             return new VarHandleBooleans.Array(aoffset, ashift);
 197         }
 198         else if (componentType == byte.class) {
 199             return new VarHandleBytes.Array(aoffset, ashift);
 200         }
 201         else if (componentType == short.class) {
 202             return new VarHandleShorts.Array(aoffset, ashift);
 203         }
 204         else if (componentType == char.class) {
 205             return new VarHandleChars.Array(aoffset, ashift);
 206         }
 207         else if (componentType == int.class) {
 208             return new VarHandleInts.Array(aoffset, ashift);
 209         }
 210         else if (componentType == long.class) {
 211             return new VarHandleLongs.Array(aoffset, ashift);
 212         }
 213         else if (componentType == float.class) {




  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  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 VarHandleValues.FieldInstanceReadOnly(refc, foffset, type)
  42                         : new VarHandleValues.FieldInstanceReadWrite(refc, foffset, type);
  43                 } else {
  44                     return f.isFinal() && !isWriteAllowedOnFinalFields
  45                        ? new VarHandleReferences.FieldInstanceReadOnly(refc, foffset, type)
  46                        : new VarHandleReferences.FieldInstanceReadWrite(refc, foffset, type);
  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)
  67                        : new VarHandleChars.FieldInstanceReadWrite(refc, foffset);


  86                        ? new VarHandleDoubles.FieldInstanceReadOnly(refc, foffset)
  87                        : new VarHandleDoubles.FieldInstanceReadWrite(refc, foffset);
  88             }
  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                 if (f.isFlattened()) {
 107                     return f.isFinal() && !isWriteAllowedOnFinalFields
 108                             ? new VarHandleValues.FieldStaticReadOnly(refc, foffset, type)
 109                             : new VarHandleValues.FieldStaticReadWrite(refc, foffset, type);
 110                 } else {
 111                     return f.isFinal() && !isWriteAllowedOnFinalFields
 112                             ? new VarHandleReferences.FieldStaticReadOnly(base, foffset, type)
 113                             : new VarHandleReferences.FieldStaticReadWrite(base, foffset, type);
 114                 }
 115             }
 116             else if (type == boolean.class) {
 117                 return f.isFinal() && !isWriteAllowedOnFinalFields
 118                        ? new VarHandleBooleans.FieldStaticReadOnly(base, foffset)
 119                        : new VarHandleBooleans.FieldStaticReadWrite(base, foffset);
 120             }
 121             else if (type == byte.class) {
 122                 return f.isFinal() && !isWriteAllowedOnFinalFields
 123                        ? new VarHandleBytes.FieldStaticReadOnly(base, foffset)
 124                        : new VarHandleBytes.FieldStaticReadWrite(base, foffset);
 125             }
 126             else if (type == short.class) {
 127                 return f.isFinal() && !isWriteAllowedOnFinalFields
 128                        ? new VarHandleShorts.FieldStaticReadOnly(base, foffset)
 129                        : new VarHandleShorts.FieldStaticReadWrite(base, foffset);
 130             }
 131             else if (type == char.class) {
 132                 return f.isFinal() && !isWriteAllowedOnFinalFields
 133                        ? new VarHandleChars.FieldStaticReadOnly(base, foffset)
 134                        : new VarHandleChars.FieldStaticReadWrite(base, foffset);


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


< prev index next >