changeset 6569:dcad13b2f6e8

use of JumpNodes to lower instanceof snippets can be disabled with graal.instanceof.disableJumpNodes system property
author Doug Simon <doug.simon@oracle.com>
date Mon, 22 Oct 2012 20:22:50 +0200
parents d8408e5563e5
children d4f5301e9c7b a9a50f21e000
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/InstanceOfSnippets.java
diffstat 1 files changed, 55 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/InstanceOfSnippets.java	Mon Oct 22 18:10:04 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/InstanceOfSnippets.java	Mon Oct 22 20:22:50 2012 +0200
@@ -48,6 +48,7 @@
 import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.snippets.SnippetTemplate.Arguments;
 import com.oracle.graal.snippets.SnippetTemplate.Key;
+import com.oracle.graal.snippets.SnippetTemplate.UsageReplacer;
 import com.oracle.graal.snippets.nodes.*;
 
 /**
@@ -297,6 +298,8 @@
             materializeSecondary = snippet("materializeSecondary", Object.class, Object.class, Object.class, Object.class, Object[].class, boolean.class);
         }
 
+        private static final boolean MATERIALIZE_IF_NODE_USAGES = Boolean.getBoolean("graal.instanceof.disableJumpNodes");
+
         public void lower(InstanceOfNode instanceOf, LoweringTool tool) {
             ValueNode hub = instanceOf.targetClassInstruction();
             ValueNode object = instanceOf.object();
@@ -310,30 +313,65 @@
 
                 // instanceof nodes are lowered separately for each usage. To simply graph modifications,
                 // we duplicate the instanceof node for each usage.
-                InstanceOfNode duplicate = instanceOf.graph().add(new InstanceOfNode(instanceOf.targetClassInstruction(), instanceOf.targetClass(), instanceOf.object(), instanceOf.profile()));
+                final InstanceOfNode duplicate = instanceOf.graph().add(new InstanceOfNode(instanceOf.targetClassInstruction(), instanceOf.targetClass(), instanceOf.object(), instanceOf.profile()));
                 usage.replaceFirstInput(instanceOf, duplicate);
 
                 if (usage instanceof IfNode) {
+                    final StructuredGraph graph = (StructuredGraph) usage.graph();
+                    if (!MATERIALIZE_IF_NODE_USAGES) {
 
-                    IfNode ifNode = (IfNode) usage;
-                    if (hintInfo.exact) {
-                        HotSpotKlassOop[] hints = createHints(hintInfo);
-                        assert hints.length == 1;
-                        key = new Key(ifExact).add("checkNull", checkNull);
-                        arguments = arguments("object", object).add("exactHub", hints[0]);
-                    } else if (target.isPrimaryType()) {
-                        key = new Key(ifPrimary).add("checkNull", checkNull).add("superCheckOffset", target.superCheckOffset());
-                        arguments = arguments("hub", hub).add("object", object);
+                        IfNode ifNode = (IfNode) usage;
+                        if (hintInfo.exact) {
+                            HotSpotKlassOop[] hints = createHints(hintInfo);
+                            assert hints.length == 1;
+                            key = new Key(ifExact).add("checkNull", checkNull);
+                            arguments = arguments("object", object).add("exactHub", hints[0]);
+                        } else if (target.isPrimaryType()) {
+                            key = new Key(ifPrimary).add("checkNull", checkNull).add("superCheckOffset", target.superCheckOffset());
+                            arguments = arguments("hub", hub).add("object", object);
+                        } else {
+                            HotSpotKlassOop[] hints = createHints(hintInfo);
+                            key = new Key(ifSecondary).add("hints", vargargs(Object.class, hints.length)).add("checkNull", checkNull);
+                            arguments = arguments("hub", hub).add("object", object).add("hints", hints);
+                        }
+
+                        SnippetTemplate template = cache.get(key);
+                        template.instantiate(runtime, duplicate, ifNode, arguments);
+                        assert ifNode.isDeleted();
+
                     } else {
-                        HotSpotKlassOop[] hints = createHints(hintInfo);
-                        key = new Key(ifSecondary).add("hints", vargargs(Object.class, hints.length)).add("checkNull", checkNull);
-                        arguments = arguments("hub", hub).add("object", object).add("hints", hints);
+
+                        final ValueNode falseValue = ConstantNode.forInt(0, graph);
+                        final ValueNode trueValue = ConstantNode.forInt(1, graph);
+
+                        if (hintInfo.exact) {
+                            HotSpotKlassOop[] hints = createHints(hintInfo);
+                            assert hints.length == 1;
+                            key = new Key(materializeExact).add("checkNull", checkNull);
+                            arguments = arguments("object", object).add("exactHub", hints[0]).add("trueValue", trueValue).add("falseValue", falseValue);
+                        } else if (target.isPrimaryType()) {
+                            key = new Key(materializePrimary).add("checkNull", checkNull).add("superCheckOffset", target.superCheckOffset());
+                            arguments = arguments("hub", hub).add("object", object).add("trueValue", trueValue).add("falseValue", falseValue);
+                        } else {
+                            HotSpotKlassOop[] hints = createHints(hintInfo);
+                            key = new Key(materializeSecondary).add("hints", vargargs(Object.class, hints.length)).add("checkNull", checkNull);
+                            arguments = arguments("hub", hub).add("object", object).add("hints", hints).add("trueValue", trueValue).add("falseValue", falseValue);
+                        }
+
+                        UsageReplacer replacer = new UsageReplacer() {
+                            @Override
+                            public void replace(ValueNode oldNode, ValueNode newNode) {
+                                assert oldNode == duplicate;
+                                newNode.inferStamp();
+                                IntegerEqualsNode condition = graph.add(new IntegerEqualsNode(newNode, trueValue));
+                                oldNode.replaceAtUsages(condition);
+                            }
+                        };
+
+                        SnippetTemplate template = cache.get(key);
+                        template.instantiate(runtime, duplicate, replacer, tool.lastFixedNode(), arguments);
                     }
 
-                    SnippetTemplate template = cache.get(key);
-                    template.instantiate(runtime, duplicate, ifNode, arguments);
-                    assert ifNode.isDeleted();
-
                 } else if (usage instanceof ConditionalNode) {
 
                     ConditionalNode materialize = (ConditionalNode) usage;