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