5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package jdk.vm.ci.hotspot;
24
25 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
26 import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
27
28 import java.lang.annotation.Annotation;
29 import java.lang.reflect.Field;
30
31 import jdk.internal.vm.annotation.Stable;
32 import jdk.vm.ci.common.JVMCIError;
33 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
34 import jdk.vm.ci.meta.JavaType;
35 import jdk.vm.ci.meta.LocationIdentity;
36 import jdk.vm.ci.meta.MetaAccessProvider;
37 import jdk.vm.ci.meta.ModifiersProvider;
38 import jdk.vm.ci.meta.ResolvedJavaField;
39 import jdk.vm.ci.meta.ResolvedJavaType;
40
41 /**
42 * Represents a field in a HotSpot type.
43 */
44 class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotProxified {
45
174 public int offset() {
175 return offset;
176 }
177
178 @Override
179 public String toString() {
180 return format("HotSpotField<%H.%n %t:") + offset + ">";
181 }
182
183 @Override
184 public boolean isSynthetic() {
185 return (config().jvmAccSynthetic & modifiers) != 0;
186 }
187
188 /**
189 * Checks if this field has the {@link Stable} annotation.
190 *
191 * @return true if field has {@link Stable} annotation, false otherwise
192 */
193 public boolean isStable() {
194 if ((config().jvmAccFieldStable & modifiers) != 0) {
195 return true;
196 }
197 assert getAnnotation(Stable.class) == null;
198 if (Option.ImplicitStableValues.getBoolean() && isImplicitStableField()) {
199 return true;
200 }
201 return false;
202 }
203
204 @Override
205 public Annotation[] getAnnotations() {
206 Field javaField = toJava();
207 if (javaField != null) {
208 return javaField.getAnnotations();
209 }
210 return new Annotation[0];
211 }
212
213 @Override
214 public Annotation[] getDeclaredAnnotations() {
215 Field javaField = toJava();
216 if (javaField != null) {
217 return javaField.getDeclaredAnnotations();
218 }
219 return new Annotation[0];
220 }
221
225 if (javaField != null) {
226 return javaField.getAnnotation(annotationClass);
227 }
228 return null;
229 }
230
231 private Field toJavaCache;
232
233 private Field toJava() {
234 if (toJavaCache != null) {
235 return toJavaCache;
236 }
237
238 if (isInternal()) {
239 return null;
240 }
241 try {
242 return toJavaCache = holder.mirror().getDeclaredField(name);
243 } catch (NoSuchFieldException | NoClassDefFoundError e) {
244 return null;
245 }
246 }
247
248 private boolean isArray() {
249 JavaType fieldType = getType();
250 return fieldType instanceof ResolvedJavaType && ((ResolvedJavaType) fieldType).isArray();
251 }
252
253 private boolean isImplicitStableField() {
254 if (isSyntheticEnumSwitchMap()) {
255 return true;
256 }
257 if (isWellKnownImplicitStableField()) {
258 return true;
259 }
260 return false;
261 }
262
263 public boolean isDefaultStable() {
264 assert this.isStable();
265 if (isSyntheticEnumSwitchMap()) {
266 return true;
267 }
268 return false;
269 }
270
271 private boolean isSyntheticEnumSwitchMap() {
272 if (isSynthetic() && isStatic() && isArray()) {
273 if (isFinal() && name.equals("$VALUES") || name.equals("ENUM$VALUES")) {
274 // generated int[] field for EnumClass::values()
275 return true;
276 } else if (name.startsWith("$SwitchMap$") || name.startsWith("$SWITCH_TABLE$")) {
277 // javac and ecj generate a static field in an inner class for a switch on an enum
278 // named $SwitchMap$p$k$g$EnumClass and $SWITCH_TABLE$p$k$g$EnumClass, respectively
279 return true;
280 }
281 }
282 return false;
283 }
284
285 private boolean isWellKnownImplicitStableField() {
286 return WellKnownImplicitStableField.test(this);
287 }
288
289 static class WellKnownImplicitStableField {
290 /**
291 * @return {@code true} if the field is a well-known stable field.
292 */
293 public static boolean test(HotSpotResolvedJavaField field) {
294 return field.equals(STRING_VALUE_FIELD);
295 }
296
297 private static final ResolvedJavaField STRING_VALUE_FIELD;
298
299 static {
300 try {
301 MetaAccessProvider metaAccess = runtime().getHostJVMCIBackend().getMetaAccess();
302 STRING_VALUE_FIELD = metaAccess.lookupJavaField(String.class.getDeclaredField("value"));
303 } catch (SecurityException | NoSuchFieldException e) {
304 throw new JVMCIError(e);
305 }
306 }
307 }
308
309 public LocationIdentity getLocationIdentity() {
310 return locationIdentity;
311 }
312 }
|
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package jdk.vm.ci.hotspot;
24
25 import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
26
27 import java.lang.annotation.Annotation;
28 import java.lang.reflect.Field;
29
30 import jdk.internal.vm.annotation.Stable;
31 import jdk.vm.ci.common.JVMCIError;
32 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
33 import jdk.vm.ci.meta.JavaType;
34 import jdk.vm.ci.meta.LocationIdentity;
35 import jdk.vm.ci.meta.MetaAccessProvider;
36 import jdk.vm.ci.meta.ModifiersProvider;
37 import jdk.vm.ci.meta.ResolvedJavaField;
38 import jdk.vm.ci.meta.ResolvedJavaType;
39
40 /**
41 * Represents a field in a HotSpot type.
42 */
43 class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotProxified {
44
173 public int offset() {
174 return offset;
175 }
176
177 @Override
178 public String toString() {
179 return format("HotSpotField<%H.%n %t:") + offset + ">";
180 }
181
182 @Override
183 public boolean isSynthetic() {
184 return (config().jvmAccSynthetic & modifiers) != 0;
185 }
186
187 /**
188 * Checks if this field has the {@link Stable} annotation.
189 *
190 * @return true if field has {@link Stable} annotation, false otherwise
191 */
192 public boolean isStable() {
193 return (config().jvmAccFieldStable & modifiers) != 0;
194 }
195
196 @Override
197 public Annotation[] getAnnotations() {
198 Field javaField = toJava();
199 if (javaField != null) {
200 return javaField.getAnnotations();
201 }
202 return new Annotation[0];
203 }
204
205 @Override
206 public Annotation[] getDeclaredAnnotations() {
207 Field javaField = toJava();
208 if (javaField != null) {
209 return javaField.getDeclaredAnnotations();
210 }
211 return new Annotation[0];
212 }
213
217 if (javaField != null) {
218 return javaField.getAnnotation(annotationClass);
219 }
220 return null;
221 }
222
223 private Field toJavaCache;
224
225 private Field toJava() {
226 if (toJavaCache != null) {
227 return toJavaCache;
228 }
229
230 if (isInternal()) {
231 return null;
232 }
233 try {
234 return toJavaCache = holder.mirror().getDeclaredField(name);
235 } catch (NoSuchFieldException | NoClassDefFoundError e) {
236 return null;
237 }
238 }
239
240 public LocationIdentity getLocationIdentity() {
241 return locationIdentity;
242 }
243 }
|