35 |
35 |
36 import java.lang.reflect.Array; |
36 import java.lang.reflect.Array; |
37 import java.lang.reflect.Field; |
37 import java.lang.reflect.Field; |
38 import java.util.Arrays; |
38 import java.util.Arrays; |
39 |
39 |
|
40 import jdk.vm.ci.code.BytecodePosition; |
|
41 import jdk.vm.ci.meta.SpeculationLog; |
40 import org.graalvm.compiler.api.directives.GraalDirectives; |
42 import org.graalvm.compiler.api.directives.GraalDirectives; |
41 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; |
43 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider; |
42 import org.graalvm.compiler.bytecode.BytecodeProvider; |
44 import org.graalvm.compiler.bytecode.BytecodeProvider; |
43 import org.graalvm.compiler.core.common.calc.Condition; |
45 import org.graalvm.compiler.core.common.calc.Condition; |
|
46 import org.graalvm.compiler.core.common.calc.Condition.CanonicalizedCondition; |
44 import org.graalvm.compiler.core.common.calc.UnsignedMath; |
47 import org.graalvm.compiler.core.common.calc.UnsignedMath; |
45 import org.graalvm.compiler.core.common.type.ObjectStamp; |
48 import org.graalvm.compiler.core.common.type.ObjectStamp; |
46 import org.graalvm.compiler.core.common.type.Stamp; |
49 import org.graalvm.compiler.core.common.type.Stamp; |
47 import org.graalvm.compiler.core.common.type.StampFactory; |
50 import org.graalvm.compiler.core.common.type.StampFactory; |
48 import org.graalvm.compiler.core.common.type.TypeReference; |
51 import org.graalvm.compiler.core.common.type.TypeReference; |
454 this.condition = condition; |
457 this.condition = condition; |
455 } |
458 } |
456 |
459 |
457 @Override |
460 @Override |
458 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { |
461 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { |
459 // the mirroring and negation operations get the condition into canonical form |
462 CanonicalizedCondition canonical = condition.canonicalize(); |
460 boolean mirror = condition.canonicalMirror(); |
|
461 boolean negate = condition.canonicalNegate(); |
|
462 StructuredGraph graph = b.getGraph(); |
463 StructuredGraph graph = b.getGraph(); |
463 |
464 |
464 ValueNode lhs = mirror ? y : x; |
465 ValueNode lhs = canonical.mustMirror() ? y : x; |
465 ValueNode rhs = mirror ? x : y; |
466 ValueNode rhs = canonical.mustMirror() ? x : y; |
466 |
467 |
467 ValueNode trueValue = ConstantNode.forBoolean(!negate, graph); |
468 ValueNode trueValue = ConstantNode.forBoolean(!canonical.mustNegate(), graph); |
468 ValueNode falseValue = ConstantNode.forBoolean(negate, graph); |
469 ValueNode falseValue = ConstantNode.forBoolean(canonical.mustNegate(), graph); |
469 |
470 |
470 Condition cond = mirror ? condition.mirror() : condition; |
471 LogicNode compare = CompareNode.createCompareNode(graph, b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, canonical.getCanonicalCondition(), lhs, rhs, NodeView.DEFAULT); |
471 if (negate) { |
|
472 cond = cond.negate(); |
|
473 } |
|
474 |
|
475 LogicNode compare = CompareNode.createCompareNode(graph, b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, cond, lhs, rhs, NodeView.DEFAULT); |
|
476 b.addPush(JavaKind.Boolean, new ConditionalNode(compare, trueValue, falseValue)); |
472 b.addPush(JavaKind.Boolean, new ConditionalNode(compare, trueValue, falseValue)); |
477 return true; |
473 return true; |
478 } |
474 } |
479 } |
475 } |
480 |
476 |
726 b.add(new MembarNode(barriers)); |
722 b.add(new MembarNode(barriers)); |
727 return true; |
723 return true; |
728 } |
724 } |
729 } |
725 } |
730 |
726 |
|
727 private static final class DirectiveSpeculationReason implements SpeculationLog.SpeculationReason { |
|
728 private final BytecodePosition pos; |
|
729 |
|
730 private DirectiveSpeculationReason(BytecodePosition pos) { |
|
731 this.pos = pos; |
|
732 } |
|
733 |
|
734 @Override |
|
735 public int hashCode() { |
|
736 return pos.hashCode(); |
|
737 } |
|
738 |
|
739 @Override |
|
740 public boolean equals(Object obj) { |
|
741 return obj instanceof DirectiveSpeculationReason && ((DirectiveSpeculationReason) obj).pos.equals(this.pos); |
|
742 } |
|
743 } |
|
744 |
731 private static void registerGraalDirectivesPlugins(InvocationPlugins plugins) { |
745 private static void registerGraalDirectivesPlugins(InvocationPlugins plugins) { |
732 Registration r = new Registration(plugins, GraalDirectives.class); |
746 Registration r = new Registration(plugins, GraalDirectives.class); |
733 r.register0("deoptimize", new InvocationPlugin() { |
747 r.register0("deoptimize", new InvocationPlugin() { |
734 @Override |
748 @Override |
735 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { |
749 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { |
740 |
754 |
741 r.register0("deoptimizeAndInvalidate", new InvocationPlugin() { |
755 r.register0("deoptimizeAndInvalidate", new InvocationPlugin() { |
742 @Override |
756 @Override |
743 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { |
757 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { |
744 b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter)); |
758 b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter)); |
|
759 return true; |
|
760 } |
|
761 }); |
|
762 |
|
763 r.register0("deoptimizeAndInvalidateWithSpeculation", new InvocationPlugin() { |
|
764 @Override |
|
765 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { |
|
766 GraalError.guarantee(b.getGraph().getSpeculationLog() != null, "A speculation log is need to use `deoptimizeAndInvalidateWithSpeculation`"); |
|
767 BytecodePosition pos = new BytecodePosition(null, b.getMethod(), b.bci()); |
|
768 DirectiveSpeculationReason reason = new DirectiveSpeculationReason(pos); |
|
769 JavaConstant speculation; |
|
770 if (b.getGraph().getSpeculationLog().maySpeculate(reason)) { |
|
771 speculation = b.getGraph().getSpeculationLog().speculate(reason); |
|
772 } else { |
|
773 speculation = JavaConstant.defaultForKind(JavaKind.Object); |
|
774 } |
|
775 b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter, speculation)); |
745 return true; |
776 return true; |
746 } |
777 } |
747 }); |
778 }); |
748 |
779 |
749 r.register0("inCompiledCode", new InvocationPlugin() { |
780 r.register0("inCompiledCode", new InvocationPlugin() { |