changeset 19341:5eb28dbbeb37

Change Class.isAssignableFrom intrinsic into a snippet
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Thu, 12 Feb 2015 15:02:00 -0800
parents 60ec7b23b7af
children f7b121b82697
files graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMethodSubstitutionTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsAssignableFromNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotClassSubstitutions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ClassIsAssignableFromNode.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ClassSubstitutions.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java
diffstat 12 files changed, 206 insertions(+), 185 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMethodSubstitutionTest.java	Thu Feb 12 15:00:00 2015 -0800
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotMethodSubstitutionTest.java	Thu Feb 12 15:02:00 2015 -0800
@@ -67,7 +67,6 @@
     @Test
     public void testClassSubstitutions() {
         test("getModifiers");
-        test("isInstance");
         test("isInterface");
         test("isArray");
         test("isPrimitive");
@@ -81,9 +80,6 @@
             assertDeepEquals(c.isPrimitive(), HotSpotClassSubstitutions.isPrimitive(c));
             assertDeepEquals(c.getSuperclass(), HotSpotClassSubstitutions.getSuperclass(c));
             assertDeepEquals(c.getComponentType(), HotSpotClassSubstitutions.getComponentType(c));
-            for (Object o : new Object[]{this, new int[5], new String[2][], new Object()}) {
-                assertDeepEquals(c.isInstance(o), HotSpotClassSubstitutions.isInstance(c, o));
-            }
         }
     }
 
@@ -93,11 +89,6 @@
     }
 
     @SuppressWarnings("all")
-    public static boolean isInstance(Class<?> clazz) {
-        return clazz.isInstance(Number.class);
-    }
-
-    @SuppressWarnings("all")
     public static boolean isInterface(Class<?> clazz) {
         return clazz.isInterface();
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Thu Feb 12 15:00:00 2015 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Thu Feb 12 15:02:00 2015 -0800
@@ -119,6 +119,10 @@
             if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
                 instanceofSnippets.lower((InstanceOfDynamicNode) n, tool);
             }
+        } else if (n instanceof ClassIsAssignableFromNode) {
+            if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
+                instanceofSnippets.lower((ClassIsAssignableFromNode) n, tool);
+            }
         } else if (n instanceof NewInstanceNode) {
             if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
                 newObjectSnippets.lower((NewInstanceNode) n, registers, tool);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsAssignableFromNode.java	Thu Feb 12 15:00:00 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2014, 2014, 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.hotspot.nodes;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.hotspot.replacements.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.replacements.nodes.*;
-
-/**
- * {@link MacroNode Macro node} for {@link Class#isAssignableFrom(Class)}.
- *
- * @see HotSpotClassSubstitutions#isAssignableFrom(Class, Class)
- */
-@NodeInfo
-public final class ClassIsAssignableFromNode extends MacroStateSplitNode implements Canonicalizable {
-    public ClassIsAssignableFromNode(Invoke invoke) {
-        super(invoke);
-    }
-
-    private ValueNode getJavaClass() {
-        return arguments.get(0);
-    }
-
-    private ValueNode getOtherClass() {
-        return arguments.get(1);
-    }
-
-    @Override
-    public Node canonical(CanonicalizerTool tool) {
-        ValueNode javaClass = getJavaClass();
-        ValueNode otherClass = getOtherClass();
-        if (javaClass.isConstant() && otherClass.isConstant()) {
-            ConstantReflectionProvider constantReflection = tool.getConstantReflection();
-            ResolvedJavaType thisType = constantReflection.asJavaType(javaClass.asJavaConstant());
-            ResolvedJavaType otherType = constantReflection.asJavaType(otherClass.asJavaConstant());
-            if (thisType != null && otherType != null) {
-                return ConstantNode.forBoolean(thisType.isAssignableFrom(otherType));
-            }
-        }
-        return this;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java	Thu Feb 12 15:00:00 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, 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.hotspot.nodes;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.hotspot.replacements.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.replacements.nodes.*;
-
-/**
- * {@link MacroNode Macro node} for {@link Class#isInstance(Object)}.
- *
- * @see HotSpotClassSubstitutions#isInstance(Class, Object)
- */
-@NodeInfo
-public final class ClassIsInstanceNode extends MacroNode implements Canonicalizable {
-
-    public ClassIsInstanceNode(Invoke invoke) {
-        super(invoke);
-    }
-
-    private ValueNode getJavaClass() {
-        return arguments.get(0);
-    }
-
-    private ValueNode getObject() {
-        return arguments.get(1);
-    }
-
-    @Override
-    public Node canonical(CanonicalizerTool tool) {
-        ValueNode javaClass = getJavaClass();
-        if (javaClass.isConstant()) {
-            ValueNode object = getObject();
-            ConstantReflectionProvider constantReflection = tool.getConstantReflection();
-            ResolvedJavaType type = constantReflection.asJavaType(javaClass.asConstant());
-            if (type != null) {
-                if (type.isPrimitive()) {
-                    return ConstantNode.forBoolean(false);
-                }
-                if (object.isConstant()) {
-                    JavaConstant c = object.asJavaConstant();
-                    return ConstantNode.forBoolean(c.isNonNull() && type.isInstance(c));
-                }
-                InstanceOfNode instanceOf = new InstanceOfNode(type, object, null);
-                return new ConditionalNode(instanceOf, ConstantNode.forBoolean(true), ConstantNode.forBoolean(false));
-            }
-        }
-        return this;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotClassSubstitutions.java	Thu Feb 12 15:00:00 2015 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotClassSubstitutions.java	Thu Feb 12 15:02:00 2015 -0800
@@ -27,13 +27,9 @@
 
 import java.lang.reflect.*;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.word.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.word.*;
 
@@ -129,32 +125,6 @@
         return null;
     }
 
-    @MacroSubstitution(macro = ClassIsInstanceNode.class, isStatic = false)
-    @MethodSubstitution(isStatic = false)
-    public static boolean isInstance(Class<?> thisObj, Object obj) {
-        return ConditionalNode.materializeIsInstance(thisObj, obj);
-    }
-
-    @MacroSubstitution(macro = ClassIsAssignableFromNode.class, isStatic = false)
-    @MethodSubstitution(isStatic = false)
-    public static boolean isAssignableFrom(Class<?> thisClass, Class<?> otherClass) {
-        if (BranchProbabilityNode.probability(BranchProbabilityNode.NOT_LIKELY_PROBABILITY, otherClass == null)) {
-            DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
-            return false;
-        }
-        GuardingNode anchorNode = SnippetAnchorNode.anchor();
-        KlassPointer thisHub = ClassGetHubNode.readClass(thisClass, anchorNode);
-        KlassPointer otherHub = ClassGetHubNode.readClass(otherClass, anchorNode);
-        if (thisHub.isNull() || otherHub.isNull()) {
-            // primitive types, only true if equal.
-            return thisClass == otherClass;
-        }
-        if (!TypeCheckSnippetUtils.checkUnknownSubType(thisHub, otherHub)) {
-            return false;
-        }
-        return true;
-    }
-
     @MacroSubstitution(macro = ClassCastNode.class, isStatic = false)
     public static native Object cast(final Class<?> thisObj, Object obj);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Thu Feb 12 15:00:00 2015 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Thu Feb 12 15:02:00 2015 -0800
@@ -32,6 +32,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.ProfilingInfo.TriState;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
@@ -194,6 +195,25 @@
         return trueValue;
     }
 
+    @Snippet
+    public static Object isAssignableFrom(Class<?> thisClass, Class<?> otherClass, Object trueValue, Object falseValue) {
+        if (BranchProbabilityNode.probability(BranchProbabilityNode.NOT_FREQUENT_PROBABILITY, otherClass == null)) {
+            DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
+            return false;
+        }
+        GuardingNode anchorNode = SnippetAnchorNode.anchor();
+        KlassPointer thisHub = ClassGetHubNode.readClass(thisClass, anchorNode);
+        KlassPointer otherHub = ClassGetHubNode.readClass(otherClass, anchorNode);
+        if (thisHub.isNull() || otherHub.isNull()) {
+            // primitive types, only true if equal.
+            return thisClass == otherClass ? trueValue : falseValue;
+        }
+        if (!TypeCheckSnippetUtils.checkUnknownSubType(thisHub, otherHub)) {
+            return falseValue;
+        }
+        return trueValue;
+    }
+
     static class Options {
 
         // @formatter:off
@@ -214,6 +234,7 @@
         private final SnippetInfo instanceofPrimary = snippet(InstanceOfSnippets.class, "instanceofPrimary");
         private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary");
         private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic");
+        private final SnippetInfo isAssignableFrom = snippet(InstanceOfSnippets.class, "isAssignableFrom");
         private final long compilationThreshold;
 
         public Templates(HotSpotProviders providers, TargetDescription target, long compilationThreshold) {
@@ -264,8 +285,7 @@
                 }
                 return args;
 
-            } else {
-                assert replacer.instanceOf instanceof InstanceOfDynamicNode;
+            } else if (replacer.instanceOf instanceof InstanceOfDynamicNode) {
                 InstanceOfDynamicNode instanceOf = (InstanceOfDynamicNode) replacer.instanceOf;
                 ValueNode object = instanceOf.object();
 
@@ -275,6 +295,16 @@
                 args.add("trueValue", replacer.trueValue);
                 args.add("falseValue", replacer.falseValue);
                 return args;
+            } else if (replacer.instanceOf instanceof ClassIsAssignableFromNode) {
+                ClassIsAssignableFromNode isAssignable = (ClassIsAssignableFromNode) replacer.instanceOf;
+                Arguments args = new Arguments(isAssignableFrom, isAssignable.graph().getGuardsStage(), tool.getLoweringStage());
+                args.add("thisClass", isAssignable.getThisClass());
+                args.add("otherClass", isAssignable.getOtherClass());
+                args.add("trueValue", replacer.trueValue);
+                args.add("falseValue", replacer.falseValue);
+                return args;
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
             }
         }
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Thu Feb 12 15:00:00 2015 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Thu Feb 12 15:02:00 2015 -0800
@@ -157,4 +157,24 @@
     public static boolean materializeIsInstance(Class<?> mirror, Object object) {
         return mirror.isInstance(object);
     }
+
+    /**
+     * @param thisClass
+     * @param otherClass
+     * @param dummy a marker to make this constructor unique for the
+     *            {@link #materializeIsAssignableFrom(Class, Class, int)} NodeIntrinsic
+     */
+    public ConditionalNode(ValueNode thisClass, ValueNode otherClass, int dummy) {
+        this(thisClass.graph().unique(new ClassIsAssignableFromNode(thisClass, otherClass)));
+    }
+
+    @SuppressWarnings("unused")
+    @NodeIntrinsic
+    private static boolean materializeIsAssignableFrom(Class<?> thisClass, Class<?> otherClass, @ConstantNodeParameter int dummy) {
+        return thisClass.isAssignableFrom(otherClass);
+    }
+
+    public static boolean materializeIsAssignableFrom(Class<?> thisClass, Class<?> otherClass) {
+        return materializeIsAssignableFrom(thisClass, otherClass, 0);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ClassIsAssignableFromNode.java	Thu Feb 12 15:02:00 2015 -0800
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2014, 2015, 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.nodes.java;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * The {@code ClassIsAssignableFromNode} represents a type check against {@link Class} instead of
+ * against instances. This is used, for instance, to intrinsify
+ * {@link Class#isAssignableFrom(Class)} .
+ */
+@NodeInfo
+public final class ClassIsAssignableFromNode extends LogicNode implements Canonicalizable.Binary<ValueNode>, Lowerable {
+    @Input ValueNode thisClass;
+    @Input ValueNode otherClass;
+
+    public ClassIsAssignableFromNode(ValueNode thisClass, ValueNode otherClass) {
+        this.thisClass = thisClass;
+        this.otherClass = otherClass;
+    }
+
+    public Object getThisClass() {
+        return thisClass;
+    }
+
+    public Object getOtherClass() {
+        return otherClass;
+    }
+
+    @Override
+    public ValueNode getX() {
+        return thisClass;
+    }
+
+    @Override
+    public ValueNode getY() {
+        return otherClass;
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
+        if (forX.isConstant() && forY.isConstant()) {
+            ConstantReflectionProvider constantReflection = tool.getConstantReflection();
+            ResolvedJavaType thisType = constantReflection.asJavaType(forX.asJavaConstant());
+            ResolvedJavaType otherType = constantReflection.asJavaType(forY.asJavaConstant());
+            if (thisType != null && otherType != null) {
+                return LogicConstantNode.forBoolean(thisType.isAssignableFrom(otherType));
+            }
+        }
+        return this;
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        tool.getLowerer().lower(this, tool);
+    }
+
+}
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java	Thu Feb 12 15:00:00 2015 -0800
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java	Thu Feb 12 15:02:00 2015 -0800
@@ -177,4 +177,25 @@
     public static double longBitsToDouble(long value) {
         return Double.longBitsToDouble(value);
     }
+
+    @SuppressWarnings("all")
+    public static boolean isInstance(Class<?> clazz) {
+        return clazz.isInstance(Number.class);
+    }
+
+    @SuppressWarnings("all")
+    public static boolean isAssignableFrom(Class<?> clazz) {
+        return clazz.isInstance(Number.class);
+    }
+
+    @Test
+    public void testClassSubstitutions() {
+        test("isInstance");
+        for (Class<?> c : new Class[]{getClass(), Cloneable.class, int[].class, String[][].class}) {
+            for (Object o : new Object[]{this, new int[5], new String[2][], new Object()}) {
+                assertDeepEquals(c.isInstance(o), ClassSubstitutions.isInstance(c, o));
+                assertDeepEquals(c.isAssignableFrom(o.getClass()), ClassSubstitutions.isAssignableFrom(c, o.getClass()));
+            }
+        }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ClassSubstitutions.java	Thu Feb 12 15:02:00 2015 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, 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.replacements;
+
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.nodes.calc.*;
+
+/**
+ * Substitutions for {@link java.lang.Class} methods.
+ */
+@ClassSubstitution(java.lang.Class.class)
+public class ClassSubstitutions {
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean isInstance(Class<?> thisObj, Object obj) {
+        return ConditionalNode.materializeIsInstance(thisObj, obj);
+    }
+
+    @MethodSubstitution(isStatic = false)
+    public static boolean isAssignableFrom(Class<?> thisClass, Class<?> otherClass) {
+        return ConditionalNode.materializeIsAssignableFrom(thisClass, otherClass);
+    }
+}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java	Thu Feb 12 15:00:00 2015 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java	Thu Feb 12 15:02:00 2015 -0800
@@ -62,6 +62,7 @@
             replacements.registerSubstitutions(Short.class, ShortSubstitutions.class);
             replacements.registerSubstitutions(UnsignedMath.class, UnsignedMathSubstitutions.class);
             replacements.registerSubstitutions(Edges.class, EdgesSubstitutions.class);
+            replacements.registerSubstitutions(Class.class, ClassSubstitutions.class);
         }
         if (Options.UseBlackholeSubstitution.getValue()) {
             replacements.registerSubstitutions(new Type() {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Thu Feb 12 15:00:00 2015 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Thu Feb 12 15:02:00 2015 -0800
@@ -65,7 +65,7 @@
     protected abstract Arguments makeArguments(InstanceOfUsageReplacer replacer, LoweringTool tool);
 
     public void lower(FloatingNode instanceOf, LoweringTool tool) {
-        assert instanceOf instanceof InstanceOfNode || instanceOf instanceof InstanceOfDynamicNode;
+        assert instanceOf instanceof InstanceOfNode || instanceOf instanceof InstanceOfDynamicNode || instanceOf instanceof ClassIsAssignableFromNode;
         List<Node> usages = instanceOf.usages().snapshot();
 
         Instantiation instantiation = new Instantiation();
@@ -176,7 +176,7 @@
         public final ValueNode falseValue;
 
         public InstanceOfUsageReplacer(Instantiation instantiation, FloatingNode instanceOf, ValueNode trueValue, ValueNode falseValue) {
-            assert instanceOf instanceof InstanceOfNode || instanceOf instanceof InstanceOfDynamicNode;
+            assert instanceOf instanceof InstanceOfNode || instanceOf instanceof InstanceOfDynamicNode || instanceOf instanceof ClassIsAssignableFromNode;
             this.instantiation = instantiation;
             this.instanceOf = instanceOf;
             this.trueValue = trueValue;