changeset 19795:3362ba500371

Connect required Assumptions with answer to CHA query
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Wed, 11 Mar 2015 17:32:04 -0700
parents 00c4aa355659
children deab43a789ad
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Assumptions.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConcreteSubtypeTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FindUniqueConcreteMethodBugTest.java graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerAssumptionsTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BasicObjectCloneNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionValidAssumption.java src/share/vm/classfile/systemDictionary.hpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/graal/graalJavaAccess.hpp
diffstat 34 files changed, 476 insertions(+), 425 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Assumptions.java	Wed Mar 11 16:06:35 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,314 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.api.code;
-
-import java.io.*;
-import java.lang.invoke.*;
-import java.util.*;
-
-import com.oracle.graal.api.meta.*;
-
-/**
- * Class for recording assumptions made during compilation.
- */
-public final class Assumptions implements Serializable, Iterable<Assumptions.Assumption> {
-
-    private static final long serialVersionUID = 5152062717588239131L;
-
-    /**
-     * Abstract base class for assumptions. An assumption assumes a property of the runtime that may
-     * be invalidated by subsequent execution (e.g., that a class has no subclasses implementing
-     * {@link NoFinalizableSubclass Object.finalize()}).
-     */
-    public abstract static class Assumption implements Serializable {
-
-        private static final long serialVersionUID = -1936652569665112915L;
-    }
-
-    /**
-     * An assumption that a given class has no subclasses implementing {@link Object#finalize()}).
-     */
-    public static final class NoFinalizableSubclass extends Assumption {
-
-        private static final long serialVersionUID = 6451169735564055081L;
-
-        private ResolvedJavaType receiverType;
-
-        public NoFinalizableSubclass(ResolvedJavaType receiverType) {
-            this.receiverType = receiverType;
-        }
-
-        @Override
-        public int hashCode() {
-            return 31 + receiverType.hashCode();
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof NoFinalizableSubclass) {
-                NoFinalizableSubclass other = (NoFinalizableSubclass) obj;
-                return other.receiverType.equals(receiverType);
-            }
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            return "NoFinalizableSubclass[receiverType=" + receiverType.toJavaName() + "]";
-        }
-
-    }
-
-    /**
-     * An assumption that a given type has a given unique subtype.
-     */
-    public static final class ConcreteSubtype extends Assumption {
-
-        private static final long serialVersionUID = -1457173265437676252L;
-
-        /**
-         * Type the assumption is made about.
-         */
-        public final ResolvedJavaType context;
-
-        /**
-         * Assumed unique concrete sub-type of the context type.
-         */
-        public final ResolvedJavaType subtype;
-
-        public ConcreteSubtype(ResolvedJavaType context, ResolvedJavaType subtype) {
-            this.context = context;
-            this.subtype = subtype;
-            assert subtype.isConcrete() : subtype.toString() + " : " + context.toString();
-            assert !subtype.isArray() || subtype.getElementalType().isFinal() : subtype.toString() + " : " + context.toString();
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + context.hashCode();
-            result = prime * result + subtype.hashCode();
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof ConcreteSubtype) {
-                ConcreteSubtype other = (ConcreteSubtype) obj;
-                return other.context.equals(context) && other.subtype.equals(subtype);
-            }
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            return "ConcreteSubtype[context=" + context.toJavaName() + ", subtype=" + subtype.toJavaName() + "]";
-        }
-    }
-
-    /**
-     * An assumption that a given virtual method has a given unique implementation.
-     */
-    public static final class ConcreteMethod extends Assumption {
-
-        private static final long serialVersionUID = -7636746737947390059L;
-
-        /**
-         * A virtual (or interface) method whose unique implementation for the receiver type in
-         * {@link #context} is {@link #impl}.
-         */
-        public final ResolvedJavaMethod method;
-
-        /**
-         * A receiver type.
-         */
-        public final ResolvedJavaType context;
-
-        /**
-         * The unique implementation of {@link #method} for {@link #context}.
-         */
-        public final ResolvedJavaMethod impl;
-
-        public ConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType context, ResolvedJavaMethod impl) {
-            this.method = method;
-            this.context = context;
-            this.impl = impl;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + method.hashCode();
-            result = prime * result + context.hashCode();
-            result = prime * result + impl.hashCode();
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof ConcreteMethod) {
-                ConcreteMethod other = (ConcreteMethod) obj;
-                return other.method.equals(method) && other.context.equals(context) && other.impl.equals(impl);
-            }
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            return "ConcreteMethod[method=" + method.format("%H.%n(%p)%r") + ", context=" + context.toJavaName() + ", impl=" + impl.format("%H.%n(%p)%r") + "]";
-        }
-    }
-
-    /**
-     * An assumption that a given call site's method handle did not change.
-     */
-    public static final class CallSiteTargetValue extends Assumption {
-
-        private static final long serialVersionUID = 1732459941784550371L;
-
-        public final CallSite callSite;
-        public final MethodHandle methodHandle;
-
-        public CallSiteTargetValue(CallSite callSite, MethodHandle methodHandle) {
-            this.callSite = callSite;
-            this.methodHandle = methodHandle;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + callSite.hashCode();
-            result = prime * result + methodHandle.hashCode();
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (obj instanceof CallSiteTargetValue) {
-                CallSiteTargetValue other = (CallSiteTargetValue) obj;
-                return callSite.equals(other.callSite) && methodHandle.equals(other.methodHandle);
-            }
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            return "CallSiteTargetValue[callSite=" + callSite + ", methodHandle=" + methodHandle + "]";
-        }
-    }
-
-    private final Set<Assumption> assumptions = new HashSet<>();
-
-    /**
-     * Returns whether any assumptions have been registered.
-     *
-     * @return {@code true} if at least one assumption has been registered, {@code false} otherwise.
-     */
-    public boolean isEmpty() {
-        return assumptions.isEmpty();
-    }
-
-    @Override
-    public int hashCode() {
-        throw new UnsupportedOperationException("hashCode");
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof Assumptions) {
-            Assumptions that = (Assumptions) obj;
-            if (!this.assumptions.equals(that.assumptions)) {
-                return false;
-            }
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public Iterator<Assumption> iterator() {
-        return assumptions.iterator();
-    }
-
-    /**
-     * Records an assumption that the specified type has no finalizable subclasses.
-     *
-     * @param receiverType the type that is assumed to have no finalizable subclasses
-     */
-    public void recordNoFinalizableSubclassAssumption(ResolvedJavaType receiverType) {
-        record(new NoFinalizableSubclass(receiverType));
-    }
-
-    /**
-     * Records that {@code subtype} is the only concrete subtype in the class hierarchy below
-     * {@code context}.
-     *
-     * @param context the root of the subtree of the class hierarchy that this assumptions is about
-     * @param subtype the one concrete subtype
-     */
-    public void recordConcreteSubtype(ResolvedJavaType context, ResolvedJavaType subtype) {
-        record(new ConcreteSubtype(context, subtype));
-    }
-
-    /**
-     * Records that {@code impl} is the only possible concrete target for a virtual call to
-     * {@code method} with a receiver of type {@code context}.
-     *
-     * @param method a method that is the target of a virtual call
-     * @param context the receiver type of a call to {@code method}
-     * @param impl the concrete method that is the only possible target for the virtual call
-     */
-    public void recordConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType context, ResolvedJavaMethod impl) {
-        record(new ConcreteMethod(method, context, impl));
-    }
-
-    public void record(Assumption assumption) {
-        assumptions.add(assumption);
-    }
-
-    /**
-     * Gets a copy of the assumptions recorded in this object as an array.
-     */
-    public Assumption[] toArray() {
-        return assumptions.toArray(new Assumption[assumptions.size()]);
-    }
-
-    /**
-     * Copies assumptions recorded by another {@link Assumptions} object into this object.
-     */
-    public void record(Assumptions other) {
-        assert other != this;
-        assumptions.addAll(other.assumptions);
-    }
-
-    @Override
-    public String toString() {
-        return "Assumptions[" + assumptions + "]";
-    }
-}
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Wed Mar 11 17:32:04 2015 -0700
@@ -28,7 +28,7 @@
 import java.io.*;
 import java.util.*;
 
-import com.oracle.graal.api.code.Assumptions.Assumption;
+import com.oracle.graal.api.meta.Assumptions.Assumption;
 import com.oracle.graal.api.code.CodeUtil.RefMapFormatter;
 import com.oracle.graal.api.meta.*;
 
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java	Wed Mar 11 17:32:04 2015 -0700
@@ -25,6 +25,7 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.api.meta.JavaTypeProfile.ProfiledType;
 
 /**
@@ -95,11 +96,11 @@
         if (targetType != null && !canHaveSubtype(targetType)) {
             exact = targetType;
         } else {
-            ResolvedJavaType uniqueSubtype = targetType == null ? null : targetType.findUniqueConcreteSubtype();
-            if (uniqueSubtype != null) {
-                if (assumptions != null) {
-                    assumptions.recordConcreteSubtype(targetType, uniqueSubtype);
-                    exact = uniqueSubtype;
+            if (assumptions != null) {
+                AssumptionResult<ResolvedJavaType> uniqueSubtype = targetType == null ? null : targetType.findUniqueConcreteSubtype();
+                if (uniqueSubtype != null) {
+                    assumptions.record(uniqueSubtype);
+                    exact = uniqueSubtype.getResult();
                 } else {
                     exact = null;
                 }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Wed Mar 11 17:32:04 2015 -0700
@@ -35,6 +35,7 @@
 import sun.reflect.ConstantPool;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.compiler.common.*;
 
 /**
@@ -273,22 +274,22 @@
     }
 
     void checkConcreteSubtype(ResolvedJavaType type, ResolvedJavaType expected) {
-        ResolvedJavaType subtype = type.findUniqueConcreteSubtype();
+        AssumptionResult<ResolvedJavaType> subtype = type.findUniqueConcreteSubtype();
         if (subtype == null) {
             // findUniqueConcreteSubtype() is conservative
         } else {
             if (expected == null) {
                 assertNull(subtype);
             } else {
-                assertTrue(subtype.equals(expected));
+                assertTrue(subtype.getResult().equals(expected));
             }
         }
 
         if (!type.isArray()) {
             ResolvedJavaType arrayType = type.getArrayClass();
-            ResolvedJavaType arraySubtype = arrayType.findUniqueConcreteSubtype();
+            AssumptionResult<ResolvedJavaType> arraySubtype = arrayType.findUniqueConcreteSubtype();
             if (arraySubtype != null) {
-                assertEquals(arraySubtype, arrayType);
+                assertEquals(arraySubtype.getResult(), arrayType);
             } else {
                 // findUniqueConcreteSubtype() method is conservative
             }
@@ -617,7 +618,7 @@
     @Test
     public void findUniqueConcreteMethodTest() throws NoSuchMethodException {
         ResolvedJavaMethod thisMethod = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("findUniqueConcreteMethodTest"));
-        ResolvedJavaMethod ucm = metaAccess.lookupJavaType(getClass()).findUniqueConcreteMethod(thisMethod);
+        ResolvedJavaMethod ucm = metaAccess.lookupJavaType(getClass()).findUniqueConcreteMethod(thisMethod).getResult();
         assertEquals(thisMethod, ucm);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Assumptions.java	Wed Mar 11 17:32:04 2015 -0700
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+import java.io.*;
+import java.lang.invoke.*;
+import java.util.*;
+
+/**
+ * Class for recording assumptions made during compilation.
+ */
+public final class Assumptions implements Serializable, Iterable<Assumptions.Assumption> {
+
+    private static final long serialVersionUID = 5152062717588239131L;
+
+    /**
+     * Abstract base class for assumptions. An assumption assumes a property of the runtime that may
+     * be invalidated by subsequent execution (e.g., that a class has no subclasses implementing
+     * {@link NoFinalizableSubclass Object.finalize()}).
+     */
+    public abstract static class Assumption implements Serializable {
+
+        private static final long serialVersionUID = -1936652569665112915L;
+    }
+
+    /**
+     * A class for providing information that is only valid in association with a set of
+     * {@link Assumption}s.
+     *
+     * @param <T>
+     */
+    public static class AssumptionResult<T> {
+        Assumption[] assumptions;
+        final T result;
+
+        private static final Assumption[] EMPTY = new Assumption[0];
+
+        public AssumptionResult(T result, Assumption... assumptions) {
+            this.result = result;
+            this.assumptions = assumptions.clone();
+        }
+
+        public AssumptionResult(T result) {
+            this(result, EMPTY);
+        }
+
+        public T getResult() {
+            return result;
+        }
+
+        public void add(AssumptionResult<T> other) {
+            Assumption[] newAssumptions = Arrays.copyOf(this.assumptions, this.assumptions.length + other.assumptions.length);
+            System.arraycopy(other.assumptions, 0, newAssumptions, this.assumptions.length, other.assumptions.length);
+            this.assumptions = newAssumptions;
+        }
+    }
+
+    /**
+     * An assumption that a given class has no subclasses implementing {@link Object#finalize()}).
+     */
+    public static final class NoFinalizableSubclass extends Assumption {
+
+        private static final long serialVersionUID = 6451169735564055081L;
+
+        private ResolvedJavaType receiverType;
+
+        public NoFinalizableSubclass(ResolvedJavaType receiverType) {
+            this.receiverType = receiverType;
+        }
+
+        @Override
+        public int hashCode() {
+            return 31 + receiverType.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof NoFinalizableSubclass) {
+                NoFinalizableSubclass other = (NoFinalizableSubclass) obj;
+                return other.receiverType.equals(receiverType);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "NoFinalizableSubclass[receiverType=" + receiverType.toJavaName() + "]";
+        }
+
+    }
+
+    /**
+     * An assumption that a given type has a given unique subtype.
+     */
+    public static final class ConcreteSubtype extends Assumption {
+
+        private static final long serialVersionUID = -1457173265437676252L;
+
+        /**
+         * Type the assumption is made about.
+         */
+        public final ResolvedJavaType context;
+
+        /**
+         * Assumed unique concrete sub-type of the context type.
+         */
+        public final ResolvedJavaType subtype;
+
+        public ConcreteSubtype(ResolvedJavaType context, ResolvedJavaType subtype) {
+            this.context = context;
+            this.subtype = subtype;
+            assert subtype.isConcrete() : subtype.toString() + " : " + context.toString();
+            assert !subtype.isArray() || subtype.getElementalType().isFinal() : subtype.toString() + " : " + context.toString();
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + context.hashCode();
+            result = prime * result + subtype.hashCode();
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ConcreteSubtype) {
+                ConcreteSubtype other = (ConcreteSubtype) obj;
+                return other.context.equals(context) && other.subtype.equals(subtype);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "ConcreteSubtype[context=" + context.toJavaName() + ", subtype=" + subtype.toJavaName() + "]";
+        }
+    }
+
+    /**
+     * An assumption that a given virtual method has a given unique implementation.
+     */
+    public static final class ConcreteMethod extends Assumption {
+
+        private static final long serialVersionUID = -7636746737947390059L;
+
+        /**
+         * A virtual (or interface) method whose unique implementation for the receiver type in
+         * {@link #context} is {@link #impl}.
+         */
+        public final ResolvedJavaMethod method;
+
+        /**
+         * A receiver type.
+         */
+        public final ResolvedJavaType context;
+
+        /**
+         * The unique implementation of {@link #method} for {@link #context}.
+         */
+        public final ResolvedJavaMethod impl;
+
+        public ConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType context, ResolvedJavaMethod impl) {
+            this.method = method;
+            this.context = context;
+            this.impl = impl;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + method.hashCode();
+            result = prime * result + context.hashCode();
+            result = prime * result + impl.hashCode();
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof ConcreteMethod) {
+                ConcreteMethod other = (ConcreteMethod) obj;
+                return other.method.equals(method) && other.context.equals(context) && other.impl.equals(impl);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "ConcreteMethod[method=" + method.format("%H.%n(%p)%r") + ", context=" + context.toJavaName() + ", impl=" + impl.format("%H.%n(%p)%r") + "]";
+        }
+    }
+
+    /**
+     * An assumption that a given call site's method handle did not change.
+     */
+    public static final class CallSiteTargetValue extends Assumption {
+
+        private static final long serialVersionUID = 1732459941784550371L;
+
+        public final CallSite callSite;
+        public final MethodHandle methodHandle;
+
+        public CallSiteTargetValue(CallSite callSite, MethodHandle methodHandle) {
+            this.callSite = callSite;
+            this.methodHandle = methodHandle;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + callSite.hashCode();
+            result = prime * result + methodHandle.hashCode();
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof CallSiteTargetValue) {
+                CallSiteTargetValue other = (CallSiteTargetValue) obj;
+                return callSite.equals(other.callSite) && methodHandle.equals(other.methodHandle);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "CallSiteTargetValue[callSite=" + callSite + ", methodHandle=" + methodHandle + "]";
+        }
+    }
+
+    private final Set<Assumption> assumptions = new HashSet<>();
+
+    /**
+     * Returns whether any assumptions have been registered.
+     *
+     * @return {@code true} if at least one assumption has been registered, {@code false} otherwise.
+     */
+    public boolean isEmpty() {
+        return assumptions.isEmpty();
+    }
+
+    @Override
+    public int hashCode() {
+        throw new UnsupportedOperationException("hashCode");
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof Assumptions) {
+            Assumptions that = (Assumptions) obj;
+            if (!this.assumptions.equals(that.assumptions)) {
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public Iterator<Assumption> iterator() {
+        return assumptions.iterator();
+    }
+
+    /**
+     * Records an assumption that the specified type has no finalizable subclasses.
+     *
+     * @param receiverType the type that is assumed to have no finalizable subclasses
+     */
+    public void recordNoFinalizableSubclassAssumption(ResolvedJavaType receiverType) {
+        record(new NoFinalizableSubclass(receiverType));
+    }
+
+    /**
+     * Records that {@code subtype} is the only concrete subtype in the class hierarchy below
+     * {@code context}.
+     *
+     * @param context the root of the subtree of the class hierarchy that this assumptions is about
+     * @param subtype the one concrete subtype
+     */
+    public void recordConcreteSubtype(ResolvedJavaType context, ResolvedJavaType subtype) {
+        record(new ConcreteSubtype(context, subtype));
+    }
+
+    /**
+     * Records that {@code impl} is the only possible concrete target for a virtual call to
+     * {@code method} with a receiver of type {@code context}.
+     *
+     * @param method a method that is the target of a virtual call
+     * @param context the receiver type of a call to {@code method}
+     * @param impl the concrete method that is the only possible target for the virtual call
+     */
+    public void recordConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType context, ResolvedJavaMethod impl) {
+        record(new ConcreteMethod(method, context, impl));
+    }
+
+    public void record(AssumptionResult<?> result) {
+        for (Assumption assumption : result.assumptions) {
+            record(assumption);
+        }
+    }
+
+    public void record(Assumption assumption) {
+        assumptions.add(assumption);
+    }
+
+    /**
+     * Gets a copy of the assumptions recorded in this object as an array.
+     */
+    public Assumption[] toArray() {
+        return assumptions.toArray(new Assumption[assumptions.size()]);
+    }
+
+    /**
+     * Copies assumptions recorded by another {@link Assumptions} object into this object.
+     */
+    public void record(Assumptions other) {
+        assert other != this;
+        assumptions.addAll(other.assumptions);
+    }
+
+    @Override
+    public String toString() {
+        return "Assumptions[" + assumptions + "]";
+    }
+}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Wed Mar 11 17:32:04 2015 -0700
@@ -25,6 +25,8 @@
 import java.lang.annotation.*;
 import java.net.*;
 
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
+
 /**
  * Represents a resolved Java type. Types include primitives, objects, {@code void}, and arrays
  * thereof. Types, like fields and methods, are resolved through {@link ConstantPool constant pools}
@@ -56,7 +58,7 @@
      *
      * @return {@code true} if this class has any subclasses with finalizers
      */
-    boolean hasFinalizableSubclass();
+    AssumptionResult<Boolean> hasFinalizableSubclass();
 
     /**
      * Checks whether this type is an interface.
@@ -202,7 +204,7 @@
      *
      * @return the unique concrete subclass for this type as described above
      */
-    ResolvedJavaType findUniqueConcreteSubtype();
+    AssumptionResult<ResolvedJavaType> findUniqueConcreteSubtype();
 
     ResolvedJavaType getComponentType();
 
@@ -257,7 +259,7 @@
      * @return the unique concrete target or {@code null} if no such target exists or assumptions
      *         are not supported by this runtime
      */
-    ResolvedJavaMethod findUniqueConcreteMethod(ResolvedJavaMethod method);
+    AssumptionResult<ResolvedJavaMethod> findUniqueConcreteMethod(ResolvedJavaMethod method);
 
     /**
      * Returns the instance fields of this class, including
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConcreteSubtypeTest.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConcreteSubtypeTest.java	Wed Mar 11 17:32:04 2015 -0700
@@ -24,7 +24,7 @@
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.Assumptions.*;
+import com.oracle.graal.api.meta.Assumptions.*;
 import com.oracle.graal.nodes.*;
 
 /**
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Wed Mar 11 17:32:04 2015 -0700
@@ -28,9 +28,8 @@
 
 import org.junit.*;
 
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.Assumptions.Assumption;
-import com.oracle.graal.api.code.Assumptions.NoFinalizableSubclass;
+import com.oracle.graal.api.meta.Assumptions.Assumption;
+import com.oracle.graal.api.meta.Assumptions.NoFinalizableSubclass;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.java.*;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FindUniqueConcreteMethodBugTest.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FindUniqueConcreteMethodBugTest.java	Wed Mar 11 17:32:04 2015 -0700
@@ -25,6 +25,7 @@
 import org.junit.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 
 public class FindUniqueConcreteMethodBugTest extends GraalCompilerTest {
 
@@ -59,8 +60,8 @@
         test("getLabelLength", tenant);
 
         ResolvedJavaMethod expected = null;
-        ResolvedJavaMethod actual = getMetaAccess().lookupJavaType(AbstractPerson.class).findUniqueConcreteMethod(ifaceMethod);
-        Assert.assertEquals(expected, actual);
+        AssumptionResult<ResolvedJavaMethod> actual = getMetaAccess().lookupJavaType(AbstractPerson.class).findUniqueConcreteMethod(ifaceMethod);
+        Assert.assertEquals(expected, actual.getResult());
 
     }
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerAssumptionsTest.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerAssumptionsTest.java	Wed Mar 11 17:32:04 2015 -0700
@@ -23,7 +23,7 @@
 package com.oracle.graal.compiler.test;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.Assumptions.Assumption;
+import com.oracle.graal.api.meta.Assumptions.Assumption;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java	Wed Mar 11 17:32:04 2015 -0700
@@ -25,7 +25,6 @@
 import java.lang.invoke.*;
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.lir.*;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java	Wed Mar 11 17:32:04 2015 -0700
@@ -26,7 +26,6 @@
 
 import java.lang.invoke.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Wed Mar 11 17:32:04 2015 -0700
@@ -23,6 +23,7 @@
 package com.oracle.graal.hotspot.meta;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.hotspot.*;
 
 /**
@@ -34,7 +35,7 @@
 
     ResolvedJavaType getComponentType();
 
-    HotSpotResolvedObjectType findUniqueConcreteSubtype();
+    AssumptionResult<ResolvedJavaType> findUniqueConcreteSubtype();
 
     HotSpotResolvedObjectType getSuperclass();
 
@@ -66,7 +67,7 @@
     int getVtableLength();
 
     @Override
-    ResolvedJavaMethod findUniqueConcreteMethod(ResolvedJavaMethod method);
+    AssumptionResult<ResolvedJavaMethod> findUniqueConcreteMethod(ResolvedJavaMethod method);
 
     /**
      * Performs a fast-path check that this type is resolved in the context of a given accessing
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java	Wed Mar 11 17:32:04 2015 -0700
@@ -33,6 +33,7 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.hotspot.*;
 
@@ -139,10 +140,10 @@
     }
 
     @Override
-    public HotSpotResolvedObjectType findUniqueConcreteSubtype() {
+    public AssumptionResult<ResolvedJavaType> findUniqueConcreteSubtype() {
         HotSpotVMConfig config = runtime().getConfig();
         if (isArray()) {
-            return getElementalType().isFinal() ? this : null;
+            return getElementalType().isFinal() ? new AssumptionResult<>(this) : null;
         } else if (isInterface()) {
             HotSpotResolvedObjectTypeImpl type = getSingleImplementor();
             if (type == null) {
@@ -157,7 +158,7 @@
             if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) {
                 return null;
             }
-            return type;
+            return new AssumptionResult<>(type, new Assumptions.ConcreteSubtype(this, type));
         } else {
             HotSpotResolvedObjectTypeImpl type = this;
             while (type.isAbstract()) {
@@ -170,7 +171,7 @@
             if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) {
                 return null;
             }
-            return type;
+            return new AssumptionResult<>(type, new Assumptions.ConcreteSubtype(this, type));
         }
     }
 
@@ -281,9 +282,12 @@
     }
 
     @Override
-    public boolean hasFinalizableSubclass() {
+    public AssumptionResult<Boolean> hasFinalizableSubclass() {
         assert !isArray();
-        return runtime().getCompilerToVM().hasFinalizableSubclass(getMetaspaceKlass());
+        if (!runtime().getCompilerToVM().hasFinalizableSubclass(getMetaspaceKlass())) {
+            return new AssumptionResult<>(false, new Assumptions.NoFinalizableSubclass(this));
+        }
+        return new AssumptionResult<>(true);
     }
 
     @Override
@@ -492,7 +496,7 @@
     }
 
     @Override
-    public ResolvedJavaMethod findUniqueConcreteMethod(ResolvedJavaMethod method) {
+    public AssumptionResult<ResolvedJavaMethod> findUniqueConcreteMethod(ResolvedJavaMethod method) {
         HotSpotResolvedJavaMethod hmethod = (HotSpotResolvedJavaMethod) method;
         HotSpotResolvedObjectType declaredHolder = hmethod.getDeclaringClass();
         /*
@@ -503,7 +507,11 @@
          * a deopt instead since they can't really be used if they aren't linked yet.
          */
         if (!declaredHolder.isAssignableFrom(this) || this.isArray() || this.equals(declaredHolder) || !isLinked() || isInterface()) {
-            return hmethod.uniqueConcreteMethod(declaredHolder);
+            ResolvedJavaMethod result = hmethod.uniqueConcreteMethod(declaredHolder);
+            if (result != null) {
+                return new AssumptionResult<>(result, new Assumptions.ConcreteMethod(method, declaredHolder, result));
+            }
+            return null;
         }
         /*
          * The holder may be a subtype of the declaredHolder so make sure to resolve the method to
@@ -515,7 +523,11 @@
             return null;
         }
 
-        return resolvedMethod.uniqueConcreteMethod(this);
+        ResolvedJavaMethod result = resolvedMethod.uniqueConcreteMethod(this);
+        if (result != null) {
+            return new AssumptionResult<>(result, new Assumptions.ConcreteMethod(method, this, result));
+        }
+        return null;
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Wed Mar 11 17:32:04 2015 -0700
@@ -29,6 +29,7 @@
 import java.net.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.hotspot.*;
 
@@ -115,8 +116,8 @@
     }
 
     @Override
-    public boolean hasFinalizableSubclass() {
-        return false;
+    public AssumptionResult<Boolean> hasFinalizableSubclass() {
+        return new AssumptionResult<>(false);
     }
 
     @Override
@@ -190,12 +191,12 @@
     }
 
     @Override
-    public ResolvedJavaType findUniqueConcreteSubtype() {
-        return this;
+    public AssumptionResult<ResolvedJavaType> findUniqueConcreteSubtype() {
+        return new AssumptionResult<>(this);
     }
 
     @Override
-    public ResolvedJavaMethod findUniqueConcreteMethod(ResolvedJavaMethod method) {
+    public AssumptionResult<ResolvedJavaMethod> findUniqueConcreteMethod(ResolvedJavaMethod method) {
         return null;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java	Wed Mar 11 17:32:04 2015 -0700
@@ -26,6 +26,7 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.api.meta.MethodHandleAccessProvider.IntrinsicMethod;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.type.*;
@@ -183,9 +184,9 @@
         if (intrinsicMethod == IntrinsicMethod.LINK_TO_VIRTUAL || intrinsicMethod == IntrinsicMethod.LINK_TO_INTERFACE) {
             ResolvedJavaType receiverType = StampTool.typeOrNull(getReceiver().stamp());
             if (receiverType != null) {
-                ResolvedJavaMethod concreteMethod = receiverType.findUniqueConcreteMethod(target);
+                AssumptionResult<ResolvedJavaMethod> concreteMethod = receiverType.findUniqueConcreteMethod(target);
                 if (concreteMethod != null) {
-                    return createTargetInvokeNode(concreteMethod, intrinsicMethod);
+                    return createTargetInvokeNode(concreteMethod.getResult(), intrinsicMethod);
                 }
             }
         }
@@ -194,9 +195,9 @@
             return createTargetInvokeNode(target, intrinsicMethod);
         }
 
-        ResolvedJavaMethod concreteMethod = target.getDeclaringClass().findUniqueConcreteMethod(target);
+        AssumptionResult<ResolvedJavaMethod> concreteMethod = target.getDeclaringClass().findUniqueConcreteMethod(target);
         if (concreteMethod != null) {
-            return createTargetInvokeNode(concreteMethod, intrinsicMethod);
+            return createTargetInvokeNode(concreteMethod.getResult(), intrinsicMethod);
         }
 
         return null;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Wed Mar 11 17:32:04 2015 -0700
@@ -26,7 +26,6 @@
 
 import java.lang.reflect.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Wed Mar 11 17:32:04 2015 -0700
@@ -25,8 +25,7 @@
 import java.util.*;
 import java.util.concurrent.atomic.*;
 
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.Assumptions.Assumption;
+import com.oracle.graal.api.meta.Assumptions.Assumption;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java	Wed Mar 11 17:32:04 2015 -0700
@@ -25,6 +25,7 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
@@ -98,7 +99,7 @@
             }
         } else if (StampTool.typeOrNull(forValue) != null) {
             ResolvedJavaType type = StampTool.typeOrNull(forValue);
-            ResolvedJavaType uniqueConcrete = type.findUniqueConcreteSubtype();
+            AssumptionResult<ResolvedJavaType> uniqueConcrete = type.findUniqueConcreteSubtype();
             if (uniqueConcrete != null) {
                 // Profile is useless => remove.
                 Debug.log("Profile useless, there is enough static type information available.");
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Wed Mar 11 17:32:04 2015 -0700
@@ -23,6 +23,7 @@
 package com.oracle.graal.nodes.extended;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
@@ -72,16 +73,15 @@
         if (metaAccess != null && getValue().stamp() instanceof ObjectStamp) {
             ObjectStamp objectStamp = (ObjectStamp) getValue().stamp();
 
-            ResolvedJavaType exactType;
+            ResolvedJavaType exactType = null;
             if (objectStamp.isExactType()) {
                 exactType = objectStamp.type();
             } else if (objectStamp.type() != null && graph().getAssumptions() != null) {
-                exactType = objectStamp.type().findUniqueConcreteSubtype();
-                if (exactType != null) {
-                    graph().getAssumptions().recordConcreteSubtype(objectStamp.type(), exactType);
+                AssumptionResult<ResolvedJavaType> typeResult = objectStamp.type().findUniqueConcreteSubtype();
+                if (typeResult != null) {
+                    exactType = typeResult.getResult();
+                    graph().getAssumptions().record(typeResult);
                 }
-            } else {
-                exactType = null;
             }
 
             if (exactType != null) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Wed Mar 11 17:32:04 2015 -0700
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
@@ -72,10 +72,10 @@
             }
             Assumptions assumptions = graph().getAssumptions();
             if (type != null && assumptions != null) {
-                ResolvedJavaMethod resolvedMethod = type.findUniqueConcreteMethod(method);
+                AssumptionResult<ResolvedJavaMethod> resolvedMethod = type.findUniqueConcreteMethod(method);
                 if (resolvedMethod != null && !type.isInterface() && method.getDeclaringClass().isAssignableFrom(type)) {
-                    assumptions.recordConcreteMethod(method, type, resolvedMethod);
-                    return ConstantNode.forConstant(stamp(), resolvedMethod.getEncoding(), tool.getMetaAccess());
+                    assumptions.record(resolvedMethod);
+                    return ConstantNode.forConstant(stamp(), resolvedMethod.getResult().getEncoding(), tool.getMetaAccess());
                 }
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Wed Mar 11 17:32:04 2015 -0700
@@ -26,8 +26,8 @@
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
@@ -72,10 +72,10 @@
         }
         assert object.stamp() instanceof ObjectStamp : object + ":" + object.stamp();
         if (assumptions != null) {
-            ResolvedJavaType uniqueConcreteType = type.findUniqueConcreteSubtype();
-            if (uniqueConcreteType != null && !uniqueConcreteType.equals(type)) {
-                assumptions.recordConcreteSubtype(type, uniqueConcreteType);
-                type = uniqueConcreteType;
+            AssumptionResult<ResolvedJavaType> uniqueConcreteType = type.findUniqueConcreteSubtype();
+            if (uniqueConcreteType != null && !uniqueConcreteType.getResult().equals(type)) {
+                assumptions.record(uniqueConcreteType);
+                type = uniqueConcreteType.getResult();
             }
         }
         return new CheckCastNode(type, object, profile, forStoreCheck);
@@ -170,11 +170,11 @@
 
         Assumptions assumptions = graph().getAssumptions();
         if (assumptions != null) {
-            ResolvedJavaType exactType = type.findUniqueConcreteSubtype();
-            if (exactType != null && !exactType.equals(type)) {
+            AssumptionResult<ResolvedJavaType> exactTypeResult = type.findUniqueConcreteSubtype();
+            if (exactTypeResult != null && !exactTypeResult.getResult().equals(type)) {
                 // Propagate more precise type information to usages of the checkcast.
-                assumptions.recordConcreteSubtype(type, exactType);
-                return new CheckCastNode(exactType, object, profile, forStoreCheck);
+                assumptions.record(exactTypeResult);
+                return new CheckCastNode(exactTypeResult.getResult(), object, profile, forStoreCheck);
             }
         }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Wed Mar 11 17:32:04 2015 -0700
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
@@ -82,11 +82,11 @@
             }
             Assumptions assumptions = graph().getAssumptions();
             if (assumptions != null) {
-                ResolvedJavaType exact = stampType.findUniqueConcreteSubtype();
-                if (exact != null) {
-                    result = checkInstanceOf(forValue, exact, objectStamp.nonNull(), true);
+                AssumptionResult<ResolvedJavaType> typeResult = stampType.findUniqueConcreteSubtype();
+                if (typeResult != null) {
+                    result = checkInstanceOf(forValue, typeResult.getResult(), objectStamp.nonNull(), true);
                     if (result != null) {
-                        assumptions.recordConcreteSubtype(stampType, exact);
+                        assumptions.record(typeResult);
                         return result;
                     }
                 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Wed Mar 11 17:32:04 2015 -0700
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
@@ -126,19 +126,19 @@
             }
             Assumptions assumptions = receiver.graph().getAssumptions();
             if (assumptions != null) {
-                ResolvedJavaType uniqueConcreteType = type.findUniqueConcreteSubtype();
+                AssumptionResult<ResolvedJavaType> uniqueConcreteType = type.findUniqueConcreteSubtype();
                 if (uniqueConcreteType != null) {
-                    ResolvedJavaMethod methodFromUniqueType = uniqueConcreteType.resolveConcreteMethod(targetMethod, contextType);
+                    ResolvedJavaMethod methodFromUniqueType = uniqueConcreteType.getResult().resolveConcreteMethod(targetMethod, contextType);
                     if (methodFromUniqueType != null) {
-                        assumptions.recordConcreteSubtype(type, uniqueConcreteType);
+                        assumptions.record(uniqueConcreteType);
                         return methodFromUniqueType;
                     }
                 }
 
-                ResolvedJavaMethod uniqueConcreteMethod = type.findUniqueConcreteMethod(targetMethod);
+                AssumptionResult<ResolvedJavaMethod> uniqueConcreteMethod = type.findUniqueConcreteMethod(targetMethod);
                 if (uniqueConcreteMethod != null) {
-                    assumptions.recordConcreteMethod(targetMethod, type, uniqueConcreteMethod);
-                    return uniqueConcreteMethod;
+                    assumptions.record(uniqueConcreteMethod);
+                    return uniqueConcreteMethod.getResult();
                 }
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Wed Mar 11 17:32:04 2015 -0700
@@ -25,6 +25,8 @@
 import static com.oracle.graal.nodes.java.ForeignCallDescriptors.*;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
@@ -66,13 +68,10 @@
         ObjectStamp objectStamp = (ObjectStamp) object.stamp();
         if (objectStamp.isExactType()) {
             return objectStamp.type().hasFinalizer();
-        } else if (objectStamp.type() != null && !objectStamp.type().hasFinalizableSubclass()) {
-            // if either the declared type of receiver or the holder
-            // can be assumed to have no finalizers
-            if (assumptions != null) {
-                assumptions.recordNoFinalizableSubclassAssumption(objectStamp.type());
-                return false;
-            }
+        } else if (objectStamp.type() != null && assumptions != null) {
+            AssumptionResult<Boolean> result = objectStamp.type().hasFinalizableSubclass();
+            assumptions.record(result);
+            return result.getResult();
         }
         return true;
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java	Wed Mar 11 17:32:04 2015 -0700
@@ -24,7 +24,7 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.Assumptions.Assumption;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.CallTargetNode.InvokeKind;
@@ -38,9 +38,9 @@
  */
 public class AssumptionInlineInfo extends ExactInlineInfo {
 
-    private final Assumption takenAssumption;
+    private final AssumptionResult<?> takenAssumption;
 
-    public AssumptionInlineInfo(Invoke invoke, ResolvedJavaMethod concrete, Assumption takenAssumption) {
+    public AssumptionInlineInfo(Invoke invoke, ResolvedJavaMethod concrete, AssumptionResult<?> takenAssumption) {
         super(invoke, concrete);
         this.takenAssumption = takenAssumption;
     }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Wed Mar 11 17:32:04 2015 -0700
@@ -29,6 +29,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.debug.*;
@@ -194,17 +195,17 @@
         }
 
         if (callTarget.graph().getAssumptions() != null) {
-            ResolvedJavaType uniqueSubtype = holder.findUniqueConcreteSubtype();
+            AssumptionResult<ResolvedJavaType> uniqueSubtype = holder.findUniqueConcreteSubtype();
             if (uniqueSubtype != null) {
-                ResolvedJavaMethod resolvedMethod = uniqueSubtype.resolveConcreteMethod(targetMethod, contextType);
+                ResolvedJavaMethod resolvedMethod = uniqueSubtype.getResult().resolveConcreteMethod(targetMethod, contextType);
                 if (resolvedMethod != null) {
-                    return getAssumptionInlineInfo(invoke, resolvedMethod, new Assumptions.ConcreteSubtype(holder, uniqueSubtype));
+                    return getAssumptionInlineInfo(invoke, resolvedMethod, uniqueSubtype);
                 }
             }
 
-            ResolvedJavaMethod concrete = holder.findUniqueConcreteMethod(targetMethod);
+            AssumptionResult<ResolvedJavaMethod> concrete = holder.findUniqueConcreteMethod(targetMethod);
             if (concrete != null) {
-                return getAssumptionInlineInfo(invoke, concrete, new Assumptions.ConcreteMethod(targetMethod, holder, concrete));
+                return getAssumptionInlineInfo(invoke, concrete.getResult(), concrete);
             }
         }
 
@@ -337,7 +338,7 @@
         }
     }
 
-    private InlineInfo getAssumptionInlineInfo(Invoke invoke, ResolvedJavaMethod concrete, Assumptions.Assumption takenAssumption) {
+    private InlineInfo getAssumptionInlineInfo(Invoke invoke, ResolvedJavaMethod concrete, AssumptionResult<?> takenAssumption) {
         assert concrete.isConcrete();
         if (checkTargetConditions(invoke, concrete)) {
             return new AssumptionInlineInfo(invoke, concrete, takenAssumption);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BasicObjectCloneNode.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BasicObjectCloneNode.java	Wed Mar 11 17:32:04 2015 -0700
@@ -24,8 +24,8 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.meta.Assumptions.AssumptionResult;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodeinfo.*;
@@ -77,10 +77,10 @@
         } else if (objectStamp.isExactType()) {
             return isCloneableType(objectStamp.type(), metaAccess) ? objectStamp.type() : null;
         } else {
-            ResolvedJavaType type = objectStamp.type().findUniqueConcreteSubtype();
-            if (type != null && isCloneableType(type, metaAccess)) {
-                assumptions.recordConcreteSubtype(objectStamp.type(), type);
-                return type;
+            AssumptionResult<ResolvedJavaType> typeResult = objectStamp.type().findUniqueConcreteSubtype();
+            if (typeResult != null && isCloneableType(typeResult.getResult(), metaAccess)) {
+                assumptions.record(typeResult);
+                return typeResult.getResult();
             } else {
                 return null;
             }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Wed Mar 11 17:32:04 2015 -0700
@@ -27,7 +27,7 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.Assumptions.Assumption;
+import com.oracle.graal.api.meta.Assumptions.Assumption;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java	Wed Mar 11 17:32:04 2015 -0700
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.truffle.nodes;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.api.runtime.*;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionValidAssumption.java	Wed Mar 11 16:06:35 2015 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionValidAssumption.java	Wed Mar 11 17:32:04 2015 -0700
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.truffle.nodes;
 
-import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.truffle.*;
 
 public final class AssumptionValidAssumption extends Assumptions.Assumption {
--- a/src/share/vm/classfile/systemDictionary.hpp	Wed Mar 11 16:06:35 2015 -0700
+++ b/src/share/vm/classfile/systemDictionary.hpp	Wed Mar 11 17:32:04 2015 -0700
@@ -204,10 +204,10 @@
   GRAAL_ONLY(do_klass(HotSpotMetaspaceConstantImpl_klass,    com_oracle_graal_hotspot_meta_HotSpotMetaspaceConstantImpl,   Graal)) \
   GRAAL_ONLY(do_klass(HotSpotStackFrameReference_klass,      com_oracle_graal_hotspot_HotSpotStackFrameReference,          Graal)) \
   GRAAL_ONLY(do_klass(CompilationTask_klass,                 com_oracle_graal_hotspot_CompilationTask,                     Graal)) \
-  GRAAL_ONLY(do_klass(Assumptions_ConcreteMethod_klass,      com_oracle_graal_api_code_Assumptions_ConcreteMethod,         Graal)) \
-  GRAAL_ONLY(do_klass(Assumptions_NoFinalizableSubclass_klass, com_oracle_graal_api_code_Assumptions_NoFinalizableSubclass, Graal))\
-  GRAAL_ONLY(do_klass(Assumptions_ConcreteSubtype_klass,     com_oracle_graal_api_code_Assumptions_ConcreteSubtype,        Graal)) \
-  GRAAL_ONLY(do_klass(Assumptions_CallSiteTargetValue_klass, com_oracle_graal_api_code_Assumptions_CallSiteTargetValue,    Graal)) \
+  GRAAL_ONLY(do_klass(Assumptions_ConcreteMethod_klass,      com_oracle_graal_api_meta_Assumptions_ConcreteMethod,         Graal)) \
+  GRAAL_ONLY(do_klass(Assumptions_NoFinalizableSubclass_klass, com_oracle_graal_api_meta_Assumptions_NoFinalizableSubclass, Graal))\
+  GRAAL_ONLY(do_klass(Assumptions_ConcreteSubtype_klass,     com_oracle_graal_api_meta_Assumptions_ConcreteSubtype,        Graal)) \
+  GRAAL_ONLY(do_klass(Assumptions_CallSiteTargetValue_klass, com_oracle_graal_api_meta_Assumptions_CallSiteTargetValue,    Graal)) \
   GRAAL_ONLY(do_klass(BytecodePosition_klass,                com_oracle_graal_api_code_BytecodePosition,                   Graal)) \
   GRAAL_ONLY(do_klass(DebugInfo_klass,                       com_oracle_graal_api_code_DebugInfo,                          Graal)) \
   GRAAL_ONLY(do_klass(RegisterSaveLayout_klass,              com_oracle_graal_api_code_RegisterSaveLayout,                 Graal)) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Wed Mar 11 16:06:35 2015 -0700
+++ b/src/share/vm/classfile/vmSymbols.hpp	Wed Mar 11 17:32:04 2015 -0700
@@ -321,10 +321,10 @@
   GRAAL_ONLY(template(com_oracle_graal_api_meta_Kind,                           "com/oracle/graal/api/meta/Kind"))                                \
   GRAAL_ONLY(template(com_oracle_graal_api_meta_LIRKind,                        "com/oracle/graal/api/meta/LIRKind"))                             \
   GRAAL_ONLY(template(com_oracle_graal_api_meta_AbstractValue,                  "com/oracle/graal/api/meta/AbstractValue"))                       \
-  GRAAL_ONLY(template(com_oracle_graal_api_code_Assumptions_ConcreteSubtype,    "com/oracle/graal/api/code/Assumptions$ConcreteSubtype"))         \
-  GRAAL_ONLY(template(com_oracle_graal_api_code_Assumptions_NoFinalizableSubclass, "com/oracle/graal/api/code/Assumptions$NoFinalizableSubclass")) \
-  GRAAL_ONLY(template(com_oracle_graal_api_code_Assumptions_ConcreteMethod,     "com/oracle/graal/api/code/Assumptions$ConcreteMethod"))          \
-  GRAAL_ONLY(template(com_oracle_graal_api_code_Assumptions_CallSiteTargetValue,"com/oracle/graal/api/code/Assumptions$CallSiteTargetValue"))     \
+  GRAAL_ONLY(template(com_oracle_graal_api_meta_Assumptions_ConcreteSubtype,    "com/oracle/graal/api/meta/Assumptions$ConcreteSubtype"))         \
+  GRAAL_ONLY(template(com_oracle_graal_api_meta_Assumptions_NoFinalizableSubclass, "com/oracle/graal/api/meta/Assumptions$NoFinalizableSubclass")) \
+  GRAAL_ONLY(template(com_oracle_graal_api_meta_Assumptions_ConcreteMethod,     "com/oracle/graal/api/meta/Assumptions$ConcreteMethod"))          \
+  GRAAL_ONLY(template(com_oracle_graal_api_meta_Assumptions_CallSiteTargetValue,"com/oracle/graal/api/meta/Assumptions$CallSiteTargetValue"))     \
   GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult,              "com/oracle/graal/api/code/CompilationResult"))                   \
   GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_Call,         "com/oracle/graal/api/code/CompilationResult$Call"))              \
   GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_ConstantReference, "com/oracle/graal/api/code/CompilationResult$ConstantReference")) \
--- a/src/share/vm/graal/graalJavaAccess.hpp	Wed Mar 11 16:06:35 2015 -0700
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Wed Mar 11 17:32:04 2015 -0700
@@ -97,7 +97,7 @@
     int_field(CompilationResult, totalFrameSize)                                                                                                               \
     int_field(CompilationResult, customStackAreaOffset)                                                                                                        \
     typeArrayOop_field(CompilationResult, targetCode, "[B")                                                                                                    \
-    objArrayOop_field(CompilationResult, assumptions, "[Lcom/oracle/graal/api/code/Assumptions$Assumption;")                                                   \
+    objArrayOop_field(CompilationResult, assumptions, "[Lcom/oracle/graal/api/meta/Assumptions$Assumption;")                                                   \
     objArrayOop_field(CompilationResult, methods, "[Lcom/oracle/graal/api/meta/ResolvedJavaMethod;")                                                           \
     int_field(CompilationResult, targetCodeSize)                                                                                                               \
   end_class                                                                                                                                                    \