src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java
changeset 48861 47f19ff9903c
parent 48398 79afa4c434f6
child 49451 e06f9607f370
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java	Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java	Fri Feb 02 17:28:17 2018 -0800
@@ -37,10 +37,13 @@
 import java.lang.reflect.Field;
 import java.util.Arrays;
 
+import jdk.vm.ci.code.BytecodePosition;
+import jdk.vm.ci.meta.SpeculationLog;
 import org.graalvm.compiler.api.directives.GraalDirectives;
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.bytecode.BytecodeProvider;
 import org.graalvm.compiler.core.common.calc.Condition;
+import org.graalvm.compiler.core.common.calc.Condition.CanonicalizedCondition;
 import org.graalvm.compiler.core.common.calc.UnsignedMath;
 import org.graalvm.compiler.core.common.type.ObjectStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
@@ -456,23 +459,16 @@
 
         @Override
         public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
-            // the mirroring and negation operations get the condition into canonical form
-            boolean mirror = condition.canonicalMirror();
-            boolean negate = condition.canonicalNegate();
+            CanonicalizedCondition canonical = condition.canonicalize();
             StructuredGraph graph = b.getGraph();
 
-            ValueNode lhs = mirror ? y : x;
-            ValueNode rhs = mirror ? x : y;
-
-            ValueNode trueValue = ConstantNode.forBoolean(!negate, graph);
-            ValueNode falseValue = ConstantNode.forBoolean(negate, graph);
+            ValueNode lhs = canonical.mustMirror() ? y : x;
+            ValueNode rhs = canonical.mustMirror() ? x : y;
 
-            Condition cond = mirror ? condition.mirror() : condition;
-            if (negate) {
-                cond = cond.negate();
-            }
+            ValueNode trueValue = ConstantNode.forBoolean(!canonical.mustNegate(), graph);
+            ValueNode falseValue = ConstantNode.forBoolean(canonical.mustNegate(), graph);
 
-            LogicNode compare = CompareNode.createCompareNode(graph, b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, cond, lhs, rhs, NodeView.DEFAULT);
+            LogicNode compare = CompareNode.createCompareNode(graph, b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, canonical.getCanonicalCondition(), lhs, rhs, NodeView.DEFAULT);
             b.addPush(JavaKind.Boolean, new ConditionalNode(compare, trueValue, falseValue));
             return true;
         }
@@ -728,6 +724,24 @@
         }
     }
 
+    private static final class DirectiveSpeculationReason implements SpeculationLog.SpeculationReason {
+        private final BytecodePosition pos;
+
+        private DirectiveSpeculationReason(BytecodePosition pos) {
+            this.pos = pos;
+        }
+
+        @Override
+        public int hashCode() {
+            return pos.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            return obj instanceof DirectiveSpeculationReason && ((DirectiveSpeculationReason) obj).pos.equals(this.pos);
+        }
+    }
+
     private static void registerGraalDirectivesPlugins(InvocationPlugins plugins) {
         Registration r = new Registration(plugins, GraalDirectives.class);
         r.register0("deoptimize", new InvocationPlugin() {
@@ -746,6 +760,23 @@
             }
         });
 
+        r.register0("deoptimizeAndInvalidateWithSpeculation", new InvocationPlugin() {
+            @Override
+            public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
+                GraalError.guarantee(b.getGraph().getSpeculationLog() != null, "A speculation log is need to use `deoptimizeAndInvalidateWithSpeculation`");
+                BytecodePosition pos = new BytecodePosition(null, b.getMethod(), b.bci());
+                DirectiveSpeculationReason reason = new DirectiveSpeculationReason(pos);
+                JavaConstant speculation;
+                if (b.getGraph().getSpeculationLog().maySpeculate(reason)) {
+                    speculation = b.getGraph().getSpeculationLog().speculate(reason);
+                } else {
+                    speculation = JavaConstant.defaultForKind(JavaKind.Object);
+                }
+                b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter, speculation));
+                return true;
+            }
+        });
+
         r.register0("inCompiledCode", new InvocationPlugin() {
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {