changeset 12484:2d8a8980eda8

Canonicalize DynamicDeoptimize nodes back to Deoptimize when used with a constant reason&action
author Gilles Duboscq <duboscq@ssw.jku.at>
date Thu, 17 Oct 2013 18:18:05 +0200
parents 134671fbf973
children b433297f21c4
files graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java
diffstat 5 files changed, 115 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Thu Oct 17 18:18:05 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Thu Oct 17 18:18:05 2013 +0200
@@ -73,4 +73,8 @@
      * @return the encoded value as an integer
      */
     Constant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason);
+
+    DeoptimizationReason decodeDeoptReason(Constant constant);
+
+    DeoptimizationAction decodeDeoptAction(Constant constant);
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Thu Oct 17 18:18:05 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Thu Oct 17 18:18:05 2013 +0200
@@ -79,14 +79,29 @@
         return runtime.getCompilerToVM().getJavaField(reflectionField);
     }
 
+    private static final int ACTION_SHIFT = 0;
+    private static final int ACTION_MASK = 0x07;
+    private static final int REASON_SHIFT = 3;
+    private static final int REASON_MASK = 0x1f;
+
     @Override
     public Constant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason) {
-        final int actionShift = 0;
-        final int reasonShift = 3;
-
         int actionValue = convertDeoptAction(action);
         int reasonValue = convertDeoptReason(reason);
-        return Constant.forInt(~(((reasonValue) << reasonShift) + ((actionValue) << actionShift)));
+        Constant c = Constant.forInt(~(((reasonValue) << REASON_SHIFT) + ((actionValue) << ACTION_SHIFT)));
+        return c;
+    }
+
+    public DeoptimizationReason decodeDeoptReason(Constant constant) {
+        int reasonValue = ((~constant.asInt()) >> REASON_SHIFT) & REASON_MASK;
+        DeoptimizationReason reason = convertDeoptReason(reasonValue);
+        return reason;
+    }
+
+    public DeoptimizationAction decodeDeoptAction(Constant constant) {
+        int actionValue = ((~constant.asInt()) >> ACTION_SHIFT) & ACTION_MASK;
+        DeoptimizationAction action = convertDeoptAction(actionValue);
+        return action;
     }
 
     public int convertDeoptAction(DeoptimizationAction action) {
@@ -106,6 +121,22 @@
         }
     }
 
+    public DeoptimizationAction convertDeoptAction(int action) {
+        if (action == runtime.getConfig().deoptActionNone) {
+            return DeoptimizationAction.None;
+        } else if (action == runtime.getConfig().deoptActionMaybeRecompile) {
+            return DeoptimizationAction.RecompileIfTooManyDeopts;
+        } else if (action == runtime.getConfig().deoptActionReinterpret) {
+            return DeoptimizationAction.InvalidateReprofile;
+        } else if (action == runtime.getConfig().deoptActionMakeNotEntrant) {
+            return DeoptimizationAction.InvalidateRecompile;
+        } else if (action == runtime.getConfig().deoptActionMakeNotCompilable) {
+            return DeoptimizationAction.InvalidateStopCompiling;
+        } else {
+            throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
     public int convertDeoptReason(DeoptimizationReason reason) {
         switch (reason) {
             case None:
@@ -140,4 +171,38 @@
                 throw GraalInternalError.shouldNotReachHere();
         }
     }
+
+    public DeoptimizationReason convertDeoptReason(int reason) {
+        if (reason == runtime.getConfig().deoptReasonNone) {
+            return DeoptimizationReason.None;
+        } else if (reason == runtime.getConfig().deoptReasonNullCheck) {
+            return DeoptimizationReason.NullCheckException;
+        } else if (reason == runtime.getConfig().deoptReasonRangeCheck) {
+            return DeoptimizationReason.BoundsCheckException;
+        } else if (reason == runtime.getConfig().deoptReasonClassCheck) {
+            return DeoptimizationReason.ClassCastException;
+        } else if (reason == runtime.getConfig().deoptReasonArrayCheck) {
+            return DeoptimizationReason.ArrayStoreException;
+        } else if (reason == runtime.getConfig().deoptReasonUnreached0) {
+            return DeoptimizationReason.UnreachedCode;
+        } else if (reason == runtime.getConfig().deoptReasonTypeCheckInlining) {
+            return DeoptimizationReason.TypeCheckedInliningViolated;
+        } else if (reason == runtime.getConfig().deoptReasonOptimizedTypeCheck) {
+            return DeoptimizationReason.OptimizedTypeCheckViolated;
+        } else if (reason == runtime.getConfig().deoptReasonNotCompiledExceptionHandler) {
+            return DeoptimizationReason.NotCompiledExceptionHandler;
+        } else if (reason == runtime.getConfig().deoptReasonUnresolved) {
+            return DeoptimizationReason.Unresolved;
+        } else if (reason == runtime.getConfig().deoptReasonJsrMismatch) {
+            return DeoptimizationReason.JavaSubroutineMismatch;
+        } else if (reason == runtime.getConfig().deoptReasonDiv0Check) {
+            return DeoptimizationReason.ArithmeticException;
+        } else if (reason == runtime.getConfig().deoptReasonConstraint) {
+            return DeoptimizationReason.RuntimeConstraint;
+        } else if (reason == runtime.getConfig().deoptReasonLoopLimitCheck) {
+            return DeoptimizationReason.LoopLimitCheck;
+        } else {
+            throw GraalInternalError.shouldNotReachHere(Integer.toHexString(reason));
+        }
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Thu Oct 17 18:18:05 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Thu Oct 17 18:18:05 2013 +0200
@@ -33,6 +33,8 @@
     private final DeoptimizationReason reason;
 
     public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason) {
+        assert action != null;
+        assert reason != null;
         this.action = action;
         this.reason = reason;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java	Thu Oct 17 18:18:05 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java	Thu Oct 17 18:18:05 2013 +0200
@@ -23,9 +23,11 @@
 package com.oracle.graal.nodes;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.spi.*;
 
-public class DynamicDeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable {
+public class DynamicDeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable, Canonicalizable {
     @Input private ValueNode actionAndReason;
 
     public DynamicDeoptimizeNode(ValueNode actionAndReason) {
@@ -44,4 +46,15 @@
     public void generate(LIRGeneratorTool generator) {
         generator.emitDeoptimize(generator.operand(actionAndReason), this);
     }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        if (actionAndReason.isConstant()) {
+            Constant constant = actionAndReason.asConstant();
+            DeoptimizeNode newDeopt = graph().add(new DeoptimizeNode(tool.getMetaAccess().decodeDeoptAction(constant), tool.getMetaAccess().decodeDeoptReason(constant)));
+            newDeopt.setDeoptimizationState(getDeoptimizationState());
+            return newDeopt;
+        }
+        return this;
+    }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Thu Oct 17 18:18:05 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Thu Oct 17 18:18:05 2013 +0200
@@ -296,39 +296,39 @@
                         graph.replaceFloating((FloatingNode) node, canonical);
                     }
                 } else {
-                    assert node instanceof FixedWithNextNode && node.predecessor() != null : node + " -> " + canonical + " : node should be fixed & connected (" + node.predecessor() + ")";
-                    FixedWithNextNode fixedWithNext = (FixedWithNextNode) node;
-
+                    assert node instanceof FixedNode && node.predecessor() != null : node + " -> " + canonical + " : node should be fixed & connected (" + node.predecessor() + ")";
+                    FixedNode fixed = (FixedNode) node;
                     if (canonical instanceof ControlSinkNode) {
                         // case 7
                         FixedWithNextNode pred = (FixedWithNextNode) node.predecessor();
-                        GraphUtil.killCFG(fixedWithNext);
+                        GraphUtil.killCFG(fixed);
                         pred.setNext((FixedNode) canonical);
                         return true;
-                    }
-
-                    // When removing a fixed node, new canonicalization
-                    // opportunities for its successor may arise
-                    assert fixedWithNext.next() != null;
-                    tool.addToWorkList(fixedWithNext.next());
-
-                    if (canonical == null) {
-                        // case 3
-                        graph.removeFixed(fixedWithNext);
-                    } else if (canonical instanceof FloatingNode) {
-                        // case 4
-                        graph.replaceFixedWithFloating(fixedWithNext, (FloatingNode) canonical);
                     } else {
-                        assert canonical instanceof FixedNode;
-                        if (canonical.predecessor() == null) {
-                            assert !canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " shouldn't have successors";
-                            // case 5
-                            graph.replaceFixedWithFixed(fixedWithNext, (FixedWithNextNode) canonical);
+                        assert fixed instanceof FixedWithNextNode;
+                        FixedWithNextNode fixedWithNext = (FixedWithNextNode) fixed;
+                        // When removing a fixed node, new canonicalization
+                        // opportunities for its successor may arise
+                        assert fixedWithNext.next() != null;
+                        tool.addToWorkList(fixedWithNext.next());
+                        if (canonical == null) {
+                            // case 3
+                            graph.removeFixed(fixedWithNext);
+                        } else if (canonical instanceof FloatingNode) {
+                            // case 4
+                            graph.replaceFixedWithFloating(fixedWithNext, (FloatingNode) canonical);
                         } else {
-                            assert canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " should have successors";
-                            // case 6
-                            node.replaceAtUsages(canonical);
-                            graph.removeFixed(fixedWithNext);
+                            assert canonical instanceof FixedNode;
+                            if (canonical.predecessor() == null) {
+                                assert !canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " shouldn't have successors";
+                                // case 5
+                                graph.replaceFixedWithFixed(fixedWithNext, (FixedWithNextNode) canonical);
+                            } else {
+                                assert canonical.cfgSuccessors().iterator().hasNext() : "replacement " + canonical + " should have successors";
+                                // case 6
+                                node.replaceAtUsages(canonical);
+                                graph.removeFixed(fixedWithNext);
+                            }
                         }
                     }
                 }