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);
|