changeset 8390:acc24060b64f

Use implicit null checks for all null checks
author Gilles Duboscq <duboscq@ssw.jku.at>
date Mon, 18 Mar 2013 14:45:36 +0100
parents e53b31b29aa4
children d1d486c03e8a
files graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java
diffstat 7 files changed, 101 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Tue Mar 19 17:03:13 2013 +0100
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Mon Mar 18 14:45:36 2013 +0100
@@ -369,6 +369,14 @@
     }
 
     @Override
+    public void emitNullCheck(ValueNode v) {
+        assert v.kind() == Kind.Object;
+        Variable obj = newVariable(Kind.Object);
+        emitMove(obj, operand(v));
+        append(new AMD64Move.NullCheckOp(obj, state()));
+    }
+
+    @Override
     public Variable emitNegate(Value inputVal) {
         AllocatableValue input = asAllocatable(inputVal);
         Variable result = newVariable(input.getKind());
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Tue Mar 19 17:03:13 2013 +0100
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Mon Mar 18 14:45:36 2013 +0100
@@ -472,4 +472,9 @@
         // TODO Auto-generated method stub
 
     }
+
+    @Override
+    public void emitNullCheck(ValueNode v) {
+        throw new InternalError("NYI");
+    }
 }
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Tue Mar 19 17:03:13 2013 +0100
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Mon Mar 18 14:45:36 2013 +0100
@@ -365,7 +365,13 @@
 
     @Override
     public void emitUnwind(Value operand) {
-        // TODO Auto-generated method stub
+        // SPARC: Auto-generated method stub
+
+    }
+
+    @Override
+    public void emitNullCheck(ValueNode v) {
+        // SPARC: Auto-generated method stub
 
     }
 }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Tue Mar 19 17:03:13 2013 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Mon Mar 18 14:45:36 2013 +0100
@@ -297,7 +297,7 @@
 
     public static class NullCheckOp extends AMD64LIRInstruction {
 
-        @Use protected AllocatableValue input;
+        @Use({REG}) protected AllocatableValue input;
         @State protected LIRFrameState state;
 
         public NullCheckOp(Variable input, LIRFrameState state) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java	Mon Mar 18 14:45:36 2013 +0100
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2013, 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.extended;
+
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+public class NullCheckNode extends FixedWithNextNode implements LIRLowerable {
+
+    @Input public ValueNode object;
+
+    public NullCheckNode(ValueNode object) {
+        super(StampFactory.dependency());
+        this.object = object;
+    }
+
+    public ValueNode getObject() {
+        return object;
+    }
+
+    @Override
+    public void generate(LIRGeneratorTool generator) {
+        generator.emitNullCheck(object);
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Tue Mar 19 17:03:13 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Mon Mar 18 14:45:36 2013 +0100
@@ -99,6 +99,8 @@
 
     public abstract void emitDeoptimize(DeoptimizationAction action, DeoptimizationReason reason);
 
+    public abstract void emitNullCheck(ValueNode v);
+
     public abstract Value emitCall(RuntimeCallTarget callTarget, CallingConvention cc, boolean canTrap, Value... args);
 
     public abstract void emitIf(IfNode i);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Tue Mar 19 17:03:13 2013 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Mon Mar 18 14:45:36 2013 +0100
@@ -59,7 +59,7 @@
             useImplicitNullChecks(block.getBeginNode(), nodes, graph, target);
         }
         FixedWithNextNode lastFixed = block.getBeginNode();
-        BeginNode lastFastPath = null;
+        FixedWithNextNode lastFastPath = null;
         for (Node node : nodes) {
             if (!node.isAlive()) {
                 continue;
@@ -72,29 +72,38 @@
                 lastFixed = (FixedWithNextNode) node;
             } else if (node instanceof GuardNode) {
                 GuardNode guard = (GuardNode) node;
-                BeginNode fastPath = graph.add(new BeginNode());
-                BeginNode trueSuccessor;
-                BeginNode falseSuccessor;
-                DeoptimizeNode deopt = graph.add(new DeoptimizeNode(guard.action(), guard.reason()));
-                BeginNode deoptBranch = BeginNode.begin(deopt);
-                Loop loop = block.getLoop();
-                while (loop != null) {
-                    LoopExitNode exit = graph.add(new LoopExitNode(loop.loopBegin()));
-                    graph.addBeforeFixed(deopt, exit);
-                    loop = loop.parent;
+                if (guard.negated() && guard.condition() instanceof IsNullNode) {
+                    IsNullNode isNull = (IsNullNode) guard.condition();
+                    NullCheckNode nullCheck = graph.add(new NullCheckNode(isNull.object()));
+                    guard.replaceAndDelete(nullCheck);
+                    lastFixed.setNext(nullCheck);
+                    lastFixed = nullCheck;
+                    lastFastPath = nullCheck;
+                } else {
+                    BeginNode fastPath = graph.add(new BeginNode());
+                    BeginNode trueSuccessor;
+                    BeginNode falseSuccessor;
+                    DeoptimizeNode deopt = graph.add(new DeoptimizeNode(guard.action(), guard.reason()));
+                    BeginNode deoptBranch = BeginNode.begin(deopt);
+                    Loop loop = block.getLoop();
+                    while (loop != null) {
+                        LoopExitNode exit = graph.add(new LoopExitNode(loop.loopBegin()));
+                        graph.addBeforeFixed(deopt, exit);
+                        loop = loop.parent;
+                    }
+                    if (guard.negated()) {
+                        trueSuccessor = deoptBranch;
+                        falseSuccessor = fastPath;
+                    } else {
+                        trueSuccessor = fastPath;
+                        falseSuccessor = deoptBranch;
+                    }
+                    IfNode ifNode = graph.add(new IfNode(guard.condition(), trueSuccessor, falseSuccessor, trueSuccessor == fastPath ? 1 : 0));
+                    guard.replaceAndDelete(fastPath);
+                    lastFixed.setNext(ifNode);
+                    lastFixed = fastPath;
+                    lastFastPath = fastPath;
                 }
-                if (guard.negated()) {
-                    trueSuccessor = deoptBranch;
-                    falseSuccessor = fastPath;
-                } else {
-                    trueSuccessor = fastPath;
-                    falseSuccessor = deoptBranch;
-                }
-                IfNode ifNode = graph.add(new IfNode(guard.condition(), trueSuccessor, falseSuccessor, trueSuccessor == fastPath ? 1 : 0));
-                guard.replaceAndDelete(fastPath);
-                lastFixed.setNext(ifNode);
-                lastFixed = fastPath;
-                lastFastPath = fastPath;
             }
         }
     }