# HG changeset patch # User Doug Simon # Date 1383080608 -3600 # Node ID c36bdee8ca293a367f0d39bef4e9610e62588a88 # Parent 9cd8dbb8a37d670b2fb5aa115065a48e09b3b309 added type check for object before reading a field value from it during compilation diff -r 9cd8dbb8a37d -r c36bdee8ca29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Tue Oct 29 22:01:08 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Tue Oct 29 22:03:28 2013 +0100 @@ -194,28 +194,41 @@ */ assert !Modifier.isStatic(flags); Object object = receiver.asObject(); - if (Modifier.isFinal(getModifiers())) { - Constant value = readValue(receiver); - if (assumeNonStaticFinalFieldsAsFinal(object.getClass()) || !value.isDefaultForKind()) { - return value; - } - } else if (isStable()) { - Constant value = readValue(receiver); - if (assumeDefaultStableFieldsAsFinal(object.getClass()) || !value.isDefaultForKind()) { - return value; - } - } else { - Class clazz = object.getClass(); - if (StableOptionValue.class.isAssignableFrom(clazz)) { - assert getName().equals("value") : "Unexpected field in " + StableOptionValue.class.getName() + " hierarchy:" + this; - StableOptionValue option = (StableOptionValue) object; - return Constant.forObject(option.getValue()); + + // Canonicalization may attempt to process an unsafe read before + // processing a guard (e.g. a type check) for this read + // so we need to type check the object being read + if (isInObject(object)) { + if (Modifier.isFinal(getModifiers())) { + Constant value = readValue(receiver); + if (assumeNonStaticFinalFieldsAsFinal(object.getClass()) || !value.isDefaultForKind()) { + return value; + } + } else if (isStable()) { + Constant value = readValue(receiver); + if (assumeDefaultStableFieldsAsFinal(object.getClass()) || !value.isDefaultForKind()) { + return value; + } + } else { + Class clazz = object.getClass(); + if (StableOptionValue.class.isAssignableFrom(clazz)) { + assert getName().equals("value") : "Unexpected field in " + StableOptionValue.class.getName() + " hierarchy:" + this; + StableOptionValue option = (StableOptionValue) object; + return Constant.forObject(option.getValue()); + } } } } return null; } + /** + * Determines if a given object contains this field. + */ + public boolean isInObject(Object object) { + return getDeclaringClass().isAssignableFrom(HotSpotResolvedObjectType.fromClass(object.getClass())); + } + @Override public Constant readValue(Constant receiver) { if (receiver == null) { @@ -226,7 +239,9 @@ return null; } else { assert !Modifier.isStatic(flags); - return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), receiver.asObject(), offset, getKind() == Kind.Object); + Object object = receiver.asObject(); + assert object != null && isInObject(object); + return runtime().getHostProviders().getConstantReflection().readUnsafeConstant(getKind(), object, offset, getKind() == Kind.Object); } }