Mercurial > hg > truffle
changeset 12628:c36bdee8ca29
added type check for object before reading a field value from it during compilation
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Tue, 29 Oct 2013 22:03:28 +0100 |
parents | 9cd8dbb8a37d |
children | 8ba058ffbc2e |
files | graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java |
diffstat | 1 files changed, 32 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- 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); } }