< prev index next >

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

Print this page

 32 import java.lang.reflect.Method;
 33 import java.lang.reflect.Modifier;
 34 import java.nio.ByteOrder;
 35 import java.util.ArrayList;
 36 import java.util.List;
 37 import java.util.Objects;
 38 import java.util.stream.Stream;
 39 
 40 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
 41 import static java.lang.invoke.MethodHandleStatics.VAR_HANDLE_SEGMENT_FORCE_EXACT;
 42 import static java.lang.invoke.MethodHandleStatics.VAR_HANDLE_IDENTITY_ADAPT;
 43 import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
 44 
 45 final class VarHandles {
 46 
 47     static VarHandle makeFieldHandle(MemberName f, Class<?> refc, boolean isWriteAllowedOnFinalFields) {
 48         if (!f.isStatic()) {
 49             long foffset = MethodHandleNatives.objectFieldOffset(f);
 50             Class<?> type = f.getFieldType();
 51             if (!type.isPrimitive()) {
 52                 return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
 53                        ? new VarHandleReferences.FieldInstanceReadOnly(refc, foffset, type)
 54                        : new VarHandleReferences.FieldInstanceReadWrite(refc, foffset, type));







 55             }
 56             else if (type == boolean.class) {
 57                 return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
 58                        ? new VarHandleBooleans.FieldInstanceReadOnly(refc, foffset)
 59                        : new VarHandleBooleans.FieldInstanceReadWrite(refc, foffset));
 60             }
 61             else if (type == byte.class) {
 62                 return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
 63                        ? new VarHandleBytes.FieldInstanceReadOnly(refc, foffset)
 64                        : new VarHandleBytes.FieldInstanceReadWrite(refc, foffset));
 65             }
 66             else if (type == short.class) {
 67                 return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
 68                        ? new VarHandleShorts.FieldInstanceReadOnly(refc, foffset)
 69                        : new VarHandleShorts.FieldInstanceReadWrite(refc, foffset));
 70             }
 71             else if (type == char.class) {
 72                 return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
 73                        ? new VarHandleChars.FieldInstanceReadOnly(refc, foffset)
 74                        : new VarHandleChars.FieldInstanceReadWrite(refc, foffset));

 94                        : new VarHandleDoubles.FieldInstanceReadWrite(refc, foffset));
 95             }
 96             else {
 97                 throw new UnsupportedOperationException();
 98             }
 99         }
100         else {
101             Class<?> decl = f.getDeclaringClass();
102             var vh = makeStaticFieldVarHandle(decl, f, isWriteAllowedOnFinalFields);
103             return maybeAdapt(UNSAFE.shouldBeInitialized(decl)
104                     ? new LazyInitializingVarHandle(vh, decl)
105                     : vh);
106         }
107     }
108 
109     static VarHandle makeStaticFieldVarHandle(Class<?> decl, MemberName f, boolean isWriteAllowedOnFinalFields) {
110         Object base = MethodHandleNatives.staticFieldBase(f);
111         long foffset = MethodHandleNatives.staticFieldOffset(f);
112         Class<?> type = f.getFieldType();
113         if (!type.isPrimitive()) {
114             return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
115                     ? new VarHandleReferences.FieldStaticReadOnly(decl, base, foffset, type)
116                     : new VarHandleReferences.FieldStaticReadWrite(decl, base, foffset, type));








117         }
118         else if (type == boolean.class) {
119             return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
120                     ? new VarHandleBooleans.FieldStaticReadOnly(decl, base, foffset)
121                     : new VarHandleBooleans.FieldStaticReadWrite(decl, base, foffset));
122         }
123         else if (type == byte.class) {
124             return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
125                     ? new VarHandleBytes.FieldStaticReadOnly(decl, base, foffset)
126                     : new VarHandleBytes.FieldStaticReadWrite(decl, base, foffset));
127         }
128         else if (type == short.class) {
129             return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
130                     ? new VarHandleShorts.FieldStaticReadOnly(decl, base, foffset)
131                     : new VarHandleShorts.FieldStaticReadWrite(decl, base, foffset));
132         }
133         else if (type == char.class) {
134             return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
135                     ? new VarHandleChars.FieldStaticReadOnly(decl, base, foffset)
136                     : new VarHandleChars.FieldStaticReadWrite(decl, base, foffset));

184 
185             if (offset == UNSAFE.staticFieldOffset(f)) {
186                 assert f.getType() == fieldType;
187                 return f;
188             }
189         }
190         throw new InternalError("Static field not found at offset");
191     }
192 
193     static VarHandle makeArrayElementHandle(Class<?> arrayClass) {
194         if (!arrayClass.isArray())
195             throw new IllegalArgumentException("not an array: " + arrayClass);
196 
197         Class<?> componentType = arrayClass.getComponentType();
198 
199         int aoffset = UNSAFE.arrayBaseOffset(arrayClass);
200         int ascale = UNSAFE.arrayIndexScale(arrayClass);
201         int ashift = 31 - Integer.numberOfLeadingZeros(ascale);
202 
203         if (!componentType.isPrimitive()) {
204             return maybeAdapt(new VarHandleReferences.Array(aoffset, ashift, arrayClass));







205         }
206         else if (componentType == boolean.class) {
207             return maybeAdapt(new VarHandleBooleans.Array(aoffset, ashift));
208         }
209         else if (componentType == byte.class) {
210             return maybeAdapt(new VarHandleBytes.Array(aoffset, ashift));
211         }
212         else if (componentType == short.class) {
213             return maybeAdapt(new VarHandleShorts.Array(aoffset, ashift));
214         }
215         else if (componentType == char.class) {
216             return maybeAdapt(new VarHandleChars.Array(aoffset, ashift));
217         }
218         else if (componentType == int.class) {
219             return maybeAdapt(new VarHandleInts.Array(aoffset, ashift));
220         }
221         else if (componentType == long.class) {
222             return maybeAdapt(new VarHandleLongs.Array(aoffset, ashift));
223         }
224         else if (componentType == float.class) {

 32 import java.lang.reflect.Method;
 33 import java.lang.reflect.Modifier;
 34 import java.nio.ByteOrder;
 35 import java.util.ArrayList;
 36 import java.util.List;
 37 import java.util.Objects;
 38 import java.util.stream.Stream;
 39 
 40 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
 41 import static java.lang.invoke.MethodHandleStatics.VAR_HANDLE_SEGMENT_FORCE_EXACT;
 42 import static java.lang.invoke.MethodHandleStatics.VAR_HANDLE_IDENTITY_ADAPT;
 43 import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
 44 
 45 final class VarHandles {
 46 
 47     static VarHandle makeFieldHandle(MemberName f, Class<?> refc, boolean isWriteAllowedOnFinalFields) {
 48         if (!f.isStatic()) {
 49             long foffset = MethodHandleNatives.objectFieldOffset(f);
 50             Class<?> type = f.getFieldType();
 51             if (!type.isPrimitive()) {
 52                 if (f.isFlat()) {
 53                     int layout = f.getLayout();
 54                     return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
 55                         ? new VarHandleFlatValues.FieldInstanceReadOnly(refc, foffset, type, f.getCheckedFieldType(), layout)
 56                         : new VarHandleFlatValues.FieldInstanceReadWrite(refc, foffset, type, f.getCheckedFieldType(), layout));
 57                 } else {
 58                     return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
 59                        ? new VarHandleReferences.FieldInstanceReadOnly(refc, foffset, type, f.getCheckedFieldType())
 60                        : new VarHandleReferences.FieldInstanceReadWrite(refc, foffset, type, f.getCheckedFieldType()));
 61                 }
 62             }
 63             else if (type == boolean.class) {
 64                 return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
 65                        ? new VarHandleBooleans.FieldInstanceReadOnly(refc, foffset)
 66                        : new VarHandleBooleans.FieldInstanceReadWrite(refc, foffset));
 67             }
 68             else if (type == byte.class) {
 69                 return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
 70                        ? new VarHandleBytes.FieldInstanceReadOnly(refc, foffset)
 71                        : new VarHandleBytes.FieldInstanceReadWrite(refc, foffset));
 72             }
 73             else if (type == short.class) {
 74                 return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
 75                        ? new VarHandleShorts.FieldInstanceReadOnly(refc, foffset)
 76                        : new VarHandleShorts.FieldInstanceReadWrite(refc, foffset));
 77             }
 78             else if (type == char.class) {
 79                 return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
 80                        ? new VarHandleChars.FieldInstanceReadOnly(refc, foffset)
 81                        : new VarHandleChars.FieldInstanceReadWrite(refc, foffset));

101                        : new VarHandleDoubles.FieldInstanceReadWrite(refc, foffset));
102             }
103             else {
104                 throw new UnsupportedOperationException();
105             }
106         }
107         else {
108             Class<?> decl = f.getDeclaringClass();
109             var vh = makeStaticFieldVarHandle(decl, f, isWriteAllowedOnFinalFields);
110             return maybeAdapt(UNSAFE.shouldBeInitialized(decl)
111                     ? new LazyInitializingVarHandle(vh, decl)
112                     : vh);
113         }
114     }
115 
116     static VarHandle makeStaticFieldVarHandle(Class<?> decl, MemberName f, boolean isWriteAllowedOnFinalFields) {
117         Object base = MethodHandleNatives.staticFieldBase(f);
118         long foffset = MethodHandleNatives.staticFieldOffset(f);
119         Class<?> type = f.getFieldType();
120         if (!type.isPrimitive()) {
121             if (f.isFlat()) {
122                 assert false : ("static field is flat in " + decl + "." + f.getName());
123                 int layout = f.getLayout();
124                 return f.isFinal() && !isWriteAllowedOnFinalFields
125                         ? new VarHandleFlatValues.FieldStaticReadOnly(decl, base, foffset, type, f.getCheckedFieldType(), layout)
126                         : new VarHandleFlatValues.FieldStaticReadWrite(decl, base, foffset, type, f.getCheckedFieldType(), layout);
127             } else {
128                 return f.isFinal() && !isWriteAllowedOnFinalFields
129                         ? new VarHandleReferences.FieldStaticReadOnly(decl, base, foffset, type, f.getCheckedFieldType())
130                         : new VarHandleReferences.FieldStaticReadWrite(decl, base, foffset, type, f.getCheckedFieldType());
131             }
132         }
133         else if (type == boolean.class) {
134             return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
135                     ? new VarHandleBooleans.FieldStaticReadOnly(decl, base, foffset)
136                     : new VarHandleBooleans.FieldStaticReadWrite(decl, base, foffset));
137         }
138         else if (type == byte.class) {
139             return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
140                     ? new VarHandleBytes.FieldStaticReadOnly(decl, base, foffset)
141                     : new VarHandleBytes.FieldStaticReadWrite(decl, base, foffset));
142         }
143         else if (type == short.class) {
144             return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
145                     ? new VarHandleShorts.FieldStaticReadOnly(decl, base, foffset)
146                     : new VarHandleShorts.FieldStaticReadWrite(decl, base, foffset));
147         }
148         else if (type == char.class) {
149             return maybeAdapt(f.isFinal() && !isWriteAllowedOnFinalFields
150                     ? new VarHandleChars.FieldStaticReadOnly(decl, base, foffset)
151                     : new VarHandleChars.FieldStaticReadWrite(decl, base, foffset));

199 
200             if (offset == UNSAFE.staticFieldOffset(f)) {
201                 assert f.getType() == fieldType;
202                 return f;
203             }
204         }
205         throw new InternalError("Static field not found at offset");
206     }
207 
208     static VarHandle makeArrayElementHandle(Class<?> arrayClass) {
209         if (!arrayClass.isArray())
210             throw new IllegalArgumentException("not an array: " + arrayClass);
211 
212         Class<?> componentType = arrayClass.getComponentType();
213 
214         int aoffset = UNSAFE.arrayBaseOffset(arrayClass);
215         int ascale = UNSAFE.arrayIndexScale(arrayClass);
216         int ashift = 31 - Integer.numberOfLeadingZeros(ascale);
217 
218         if (!componentType.isPrimitive()) {
219             VarHandle vh;
220             if (UNSAFE.isFlatArray(arrayClass)) {
221                 int layout = UNSAFE.arrayLayout(arrayClass);
222                 vh = new VarHandleFlatValues.Array(aoffset, ashift, arrayClass, layout);
223             } else {
224                 vh = new VarHandleReferences.Array(aoffset, ashift, arrayClass);
225             }
226             return maybeAdapt(vh);
227         }
228         else if (componentType == boolean.class) {
229             return maybeAdapt(new VarHandleBooleans.Array(aoffset, ashift));
230         }
231         else if (componentType == byte.class) {
232             return maybeAdapt(new VarHandleBytes.Array(aoffset, ashift));
233         }
234         else if (componentType == short.class) {
235             return maybeAdapt(new VarHandleShorts.Array(aoffset, ashift));
236         }
237         else if (componentType == char.class) {
238             return maybeAdapt(new VarHandleChars.Array(aoffset, ashift));
239         }
240         else if (componentType == int.class) {
241             return maybeAdapt(new VarHandleInts.Array(aoffset, ashift));
242         }
243         else if (componentType == long.class) {
244             return maybeAdapt(new VarHandleLongs.Array(aoffset, ashift));
245         }
246         else if (componentType == float.class) {
< prev index next >