225 if (obj instanceof Class) {
226 return runtime.getHostJVMCIBackend().getMetaAccess().lookupJavaType((Class<?>) obj);
227 }
228 }
229 if (constant instanceof HotSpotMetaspaceConstant) {
230 MetaspaceWrapperObject obj = HotSpotMetaspaceConstantImpl.getMetaspaceObject(constant);
231 if (obj instanceof HotSpotResolvedObjectTypeImpl) {
232 return (ResolvedJavaType) obj;
233 }
234 }
235 return null;
236 }
237
238 private static final String SystemClassName = "Ljava/lang/System;";
239
240 /**
241 * Determines if a static field is constant for the purpose of
242 * {@link #readConstantFieldValue(JavaField, JavaConstant)}.
243 */
244 protected boolean isStaticFieldConstant(HotSpotResolvedJavaField staticField) {
245 if (staticField.isFinal() || staticField.isStable()) {
246 ResolvedJavaType holder = staticField.getDeclaringClass();
247 if (holder.isInitialized() && !holder.getName().equals(SystemClassName)) {
248 return true;
249 }
250 }
251 return false;
252 }
253
254 /**
255 * Determines if a value read from a {@code final} instance field is considered constant. The
256 * implementation in {@link HotSpotConstantReflectionProvider} returns true if {@code value} is
257 * not the {@link JavaConstant#isDefaultForKind default value} for its kind or if
258 * {@link Options#TrustFinalDefaultFields} is true.
259 *
260 * @param value a value read from a {@code final} instance field
261 * @param receiverClass the {@link Object#getClass() class} of object from which the
262 * {@code value} was read
263 */
264 protected boolean isFinalInstanceFieldValueConstant(JavaConstant value, Class<?> receiverClass) {
265 return !value.isDefaultForKind() || Options.TrustFinalDefaultFields.getValue();
295 }
296 }
297 } else {
298 /*
299 * for non-static final fields, we must assume that they are only initialized if they
300 * have a non-default value.
301 */
302 Object object = receiver.isNull() ? null : ((HotSpotObjectConstantImpl) receiver).object();
303
304 // Canonicalization may attempt to process an unsafe read before
305 // processing a guard (e.g. a null check or a type check) for this read
306 // so we need to check the object being read
307 if (object != null) {
308 if (hotspotField.isFinal()) {
309 if (hotspotField.isInObject(object)) {
310 JavaConstant value = readFieldValue(field, receiver);
311 if (isFinalInstanceFieldValueConstant(value, object.getClass())) {
312 return value;
313 }
314 }
315 } else if (hotspotField.isStable()) {
316 if (hotspotField.isInObject(object)) {
317 JavaConstant value = readFieldValue(field, receiver);
318 if (isStableInstanceFieldValueConstant(value, object.getClass())) {
319 return value;
320 }
321 }
322 } else {
323 Class<?> clazz = object.getClass();
324 if (StableOptionValue.class.isAssignableFrom(clazz)) {
325 if (hotspotField.isInObject(object) && hotspotField.getName().equals("value")) {
326 StableOptionValue<?> option = (StableOptionValue<?>) object;
327 return HotSpotObjectConstantImpl.forObject(option.getValue());
328 }
329 }
330 }
331 }
332 }
333 return null;
334 }
335
336 public JavaConstant readFieldValue(JavaField field, JavaConstant receiver) {
337 HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
338 if (!hotspotField.isStable()) {
339 return readNonStableFieldValue(field, receiver);
340 } else {
341 return readStableFieldValue(field, receiver, hotspotField.isDefaultStable());
342 }
343 }
344
345 private JavaConstant readNonStableFieldValue(JavaField field, JavaConstant receiver) {
346 HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
347 if (hotspotField.isStatic()) {
348 HotSpotResolvedJavaType holder = (HotSpotResolvedJavaType) hotspotField.getDeclaringClass();
349 if (holder.isInitialized()) {
350 return memoryAccess.readUnsafeConstant(hotspotField.getJavaKind(), HotSpotObjectConstantImpl.forObject(holder.mirror()), hotspotField.offset());
351 }
352 } else {
353 if (receiver.isNonNull() && hotspotField.isInObject(((HotSpotObjectConstantImpl) receiver).object())) {
354 return memoryAccess.readUnsafeConstant(hotspotField.getJavaKind(), receiver, hotspotField.offset());
355 }
356 }
357 return null;
358 }
359
360 public JavaConstant readStableFieldValue(JavaField field, JavaConstant receiver, boolean isDefaultStable) {
361 JavaConstant fieldValue = readNonStableFieldValue(field, receiver);
|
225 if (obj instanceof Class) {
226 return runtime.getHostJVMCIBackend().getMetaAccess().lookupJavaType((Class<?>) obj);
227 }
228 }
229 if (constant instanceof HotSpotMetaspaceConstant) {
230 MetaspaceWrapperObject obj = HotSpotMetaspaceConstantImpl.getMetaspaceObject(constant);
231 if (obj instanceof HotSpotResolvedObjectTypeImpl) {
232 return (ResolvedJavaType) obj;
233 }
234 }
235 return null;
236 }
237
238 private static final String SystemClassName = "Ljava/lang/System;";
239
240 /**
241 * Determines if a static field is constant for the purpose of
242 * {@link #readConstantFieldValue(JavaField, JavaConstant)}.
243 */
244 protected boolean isStaticFieldConstant(HotSpotResolvedJavaField staticField) {
245 if (staticField.isFinal() || (staticField.isStable() && runtime.getConfig().foldStableValues)) {
246 ResolvedJavaType holder = staticField.getDeclaringClass();
247 if (holder.isInitialized() && !holder.getName().equals(SystemClassName)) {
248 return true;
249 }
250 }
251 return false;
252 }
253
254 /**
255 * Determines if a value read from a {@code final} instance field is considered constant. The
256 * implementation in {@link HotSpotConstantReflectionProvider} returns true if {@code value} is
257 * not the {@link JavaConstant#isDefaultForKind default value} for its kind or if
258 * {@link Options#TrustFinalDefaultFields} is true.
259 *
260 * @param value a value read from a {@code final} instance field
261 * @param receiverClass the {@link Object#getClass() class} of object from which the
262 * {@code value} was read
263 */
264 protected boolean isFinalInstanceFieldValueConstant(JavaConstant value, Class<?> receiverClass) {
265 return !value.isDefaultForKind() || Options.TrustFinalDefaultFields.getValue();
295 }
296 }
297 } else {
298 /*
299 * for non-static final fields, we must assume that they are only initialized if they
300 * have a non-default value.
301 */
302 Object object = receiver.isNull() ? null : ((HotSpotObjectConstantImpl) receiver).object();
303
304 // Canonicalization may attempt to process an unsafe read before
305 // processing a guard (e.g. a null check or a type check) for this read
306 // so we need to check the object being read
307 if (object != null) {
308 if (hotspotField.isFinal()) {
309 if (hotspotField.isInObject(object)) {
310 JavaConstant value = readFieldValue(field, receiver);
311 if (isFinalInstanceFieldValueConstant(value, object.getClass())) {
312 return value;
313 }
314 }
315 } else if (hotspotField.isStable() && runtime.getConfig().foldStableValues) {
316 if (hotspotField.isInObject(object)) {
317 JavaConstant value = readFieldValue(field, receiver);
318 if (isStableInstanceFieldValueConstant(value, object.getClass())) {
319 return value;
320 }
321 }
322 } else {
323 Class<?> clazz = object.getClass();
324 if (StableOptionValue.class.isAssignableFrom(clazz)) {
325 if (hotspotField.isInObject(object) && hotspotField.getName().equals("value")) {
326 StableOptionValue<?> option = (StableOptionValue<?>) object;
327 return HotSpotObjectConstantImpl.forObject(option.getValue());
328 }
329 }
330 }
331 }
332 }
333 return null;
334 }
335
336 public JavaConstant readFieldValue(JavaField field, JavaConstant receiver) {
337 HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
338 if (!hotspotField.isStable()) {
339 return readNonStableFieldValue(field, receiver);
340 } else if (runtime.getConfig().foldStableValues) {
341 return readStableFieldValue(field, receiver, hotspotField.isDefaultStable());
342 } else {
343 return null;
344 }
345 }
346
347 private JavaConstant readNonStableFieldValue(JavaField field, JavaConstant receiver) {
348 HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
349 if (hotspotField.isStatic()) {
350 HotSpotResolvedJavaType holder = (HotSpotResolvedJavaType) hotspotField.getDeclaringClass();
351 if (holder.isInitialized()) {
352 return memoryAccess.readUnsafeConstant(hotspotField.getJavaKind(), HotSpotObjectConstantImpl.forObject(holder.mirror()), hotspotField.offset());
353 }
354 } else {
355 if (receiver.isNonNull() && hotspotField.isInObject(((HotSpotObjectConstantImpl) receiver).object())) {
356 return memoryAccess.readUnsafeConstant(hotspotField.getJavaKind(), receiver, hotspotField.offset());
357 }
358 }
359 return null;
360 }
361
362 public JavaConstant readStableFieldValue(JavaField field, JavaConstant receiver, boolean isDefaultStable) {
363 JavaConstant fieldValue = readNonStableFieldValue(field, receiver);
|