--- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java 2019-03-12 08:10:15.035828891 +0100 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java 2019-03-12 08:10:14.667826508 +0100 @@ -33,8 +33,8 @@ import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD; import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE; import static org.graalvm.compiler.nodes.NamedLocationIdentity.OFF_HEAP_LOCATION; -import static org.graalvm.compiler.serviceprovider.GraalServices.Java11OrEarlier; -import static org.graalvm.compiler.serviceprovider.GraalServices.Java8OrEarlier; +import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java11OrEarlier; +import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.Java8OrEarlier; import java.lang.reflect.Array; import java.lang.reflect.Field; @@ -54,8 +54,6 @@ import org.graalvm.compiler.graph.Edges; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.NodeList; -import org.graalvm.compiler.java.IntegerExactOpSpeculation; -import org.graalvm.compiler.java.IntegerExactOpSpeculation.IntegerExactOp; import org.graalvm.compiler.nodes.AbstractBeginNode; import org.graalvm.compiler.nodes.BeginNode; import org.graalvm.compiler.nodes.ConstantNode; @@ -66,6 +64,7 @@ import org.graalvm.compiler.nodes.IfNode; import org.graalvm.compiler.nodes.LogicNode; import org.graalvm.compiler.nodes.MergeNode; +import org.graalvm.compiler.nodes.NamedLocationIdentity; import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.StateSplit; import org.graalvm.compiler.nodes.StructuredGraph; @@ -93,6 +92,9 @@ import org.graalvm.compiler.nodes.extended.BranchProbabilityNode; import org.graalvm.compiler.nodes.extended.BytecodeExceptionNode.BytecodeExceptionKind; import org.graalvm.compiler.nodes.extended.GetClassNode; +import org.graalvm.compiler.nodes.extended.GuardingNode; +import org.graalvm.compiler.nodes.extended.JavaReadNode; +import org.graalvm.compiler.nodes.extended.JavaWriteNode; import org.graalvm.compiler.nodes.extended.MembarNode; import org.graalvm.compiler.nodes.extended.OpaqueNode; import org.graalvm.compiler.nodes.extended.RawLoadNode; @@ -113,6 +115,8 @@ import org.graalvm.compiler.nodes.java.RegisterFinalizerNode; import org.graalvm.compiler.nodes.java.UnsafeCompareAndExchangeNode; import org.graalvm.compiler.nodes.java.UnsafeCompareAndSwapNode; +import org.graalvm.compiler.nodes.memory.HeapAccess; +import org.graalvm.compiler.nodes.memory.address.IndexAddressNode; import org.graalvm.compiler.nodes.type.StampTool; import org.graalvm.compiler.nodes.util.GraphUtil; import org.graalvm.compiler.nodes.virtual.EnsureVirtualizedNode; @@ -120,13 +124,16 @@ import org.graalvm.compiler.replacements.nodes.ReverseBytesNode; import org.graalvm.compiler.replacements.nodes.VirtualizableInvokeMacroNode; import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerAddExactNode; +import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerAddExactOverflowNode; import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerAddExactSplitNode; -import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerExactArithmeticNode; import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerExactArithmeticSplitNode; import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerMulExactNode; +import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerMulExactOverflowNode; import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerMulExactSplitNode; import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerSubExactNode; +import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerSubExactOverflowNode; import org.graalvm.compiler.replacements.nodes.arithmetic.IntegerSubExactSplitNode; +import org.graalvm.compiler.serviceprovider.SpeculationReasonGroup; import jdk.internal.vm.compiler.word.LocationIdentity; import jdk.vm.ci.code.BytecodePosition; @@ -197,8 +204,10 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { if (receiver.isConstant()) { String s = snippetReflection.asObject(String.class, (JavaConstant) receiver.get().asConstant()); - b.addPush(JavaKind.Int, b.add(ConstantNode.forInt(s.hashCode()))); - return true; + if (s != null) { + b.addPush(JavaKind.Int, b.add(ConstantNode.forInt(s.hashCode()))); + return true; + } } return false; } @@ -221,12 +230,32 @@ }); } else { r.registerMethodSubstitution(JDK9StringSubstitutions.class, "equals", Receiver.class, Object.class); + Registration utf16sub = new Registration(plugins, StringUTF16Substitutions.class, bytecodeProvider); + utf16sub.register2("getCharDirect", byte[].class, int.class, new InvocationPlugin() { + @Override + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg1, ValueNode arg2) { + b.addPush(JavaKind.Char, new JavaReadNode(JavaKind.Char, new IndexAddressNode(arg1, arg2, JavaKind.Byte), NamedLocationIdentity.getArrayLocation(JavaKind.Byte), + HeapAccess.BarrierType.NONE, false)); + return true; + } + }); + utf16sub.register3("putCharDirect", byte[].class, int.class, int.class, new InvocationPlugin() { + @Override + public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg1, ValueNode arg2, ValueNode arg3) { + b.add(new JavaWriteNode(JavaKind.Char, new IndexAddressNode(arg1, arg2, JavaKind.Byte), NamedLocationIdentity.getArrayLocation(JavaKind.Byte), arg3, + HeapAccess.BarrierType.NONE, false)); + return true; + } + }); final Registration latin1r = new Registration(plugins, "java.lang.StringLatin1", bytecodeProvider); latin1r.register5("indexOf", byte[].class, int.class, byte[].class, int.class, int.class, new StringLatin1IndexOfConstantPlugin()); final Registration utf16r = new Registration(plugins, "java.lang.StringUTF16", bytecodeProvider); utf16r.register5("indexOfUnsafe", byte[].class, int.class, byte[].class, int.class, int.class, new StringUTF16IndexOfConstantPlugin()); + utf16r.setAllowOverwrite(true); + utf16r.registerMethodSubstitution(StringUTF16Substitutions.class, "getChar", byte[].class, int.class); + utf16r.registerMethodSubstitution(StringUTF16Substitutions.class, "putChar", byte[].class, int.class, int.class); Registration sr = new Registration(plugins, JDK9StringSubstitutions.class); sr.register1("getValue", String.class, new InvocationPlugin() { @@ -529,16 +558,47 @@ }); } - private static ValueNode createIntegerExactArithmeticNode(ValueNode x, ValueNode y, SpeculationReason speculation, IntegerExactOp op) { + public enum IntegerExactOp { + INTEGER_ADD_EXACT, + INTEGER_INCREMENT_EXACT, + INTEGER_SUBTRACT_EXACT, + INTEGER_DECREMENT_EXACT, + INTEGER_MULTIPLY_EXACT + } + + private static GuardingNode createIntegerExactArithmeticGuardNode(GraphBuilderContext b, ValueNode x, ValueNode y, IntegerExactOp op) { + LogicNode overflowCheck; + switch (op) { + case INTEGER_ADD_EXACT: + case INTEGER_INCREMENT_EXACT: { + overflowCheck = new IntegerAddExactOverflowNode(x, y); + break; + } + case INTEGER_SUBTRACT_EXACT: + case INTEGER_DECREMENT_EXACT: { + overflowCheck = new IntegerSubExactOverflowNode(x, y); + break; + } + case INTEGER_MULTIPLY_EXACT: { + overflowCheck = new IntegerMulExactOverflowNode(x, y); + break; + } + default: + throw GraalError.shouldNotReachHere("Unknown integer exact operation."); + } + return b.add(new FixedGuardNode(overflowCheck, DeoptimizationReason.ArithmeticException, DeoptimizationAction.InvalidateRecompile, true)); + } + + private static ValueNode createIntegerExactArithmeticNode(GraphBuilderContext b, ValueNode x, ValueNode y, IntegerExactOp op) { switch (op) { case INTEGER_ADD_EXACT: case INTEGER_INCREMENT_EXACT: - return new IntegerAddExactNode(x, y, speculation); + return new IntegerAddExactNode(x, y, createIntegerExactArithmeticGuardNode(b, x, y, op)); case INTEGER_SUBTRACT_EXACT: case INTEGER_DECREMENT_EXACT: - return new IntegerSubExactNode(x, y, speculation); + return new IntegerSubExactNode(x, y, createIntegerExactArithmeticGuardNode(b, x, y, op)); case INTEGER_MULTIPLY_EXACT: - return new IntegerMulExactNode(x, y, speculation); + return new IntegerMulExactNode(x, y, createIntegerExactArithmeticGuardNode(b, x, y, op)); default: throw GraalError.shouldNotReachHere("Unknown integer exact operation."); } @@ -559,15 +619,15 @@ } } - private static boolean createIntegerExactOperation(GraphBuilderContext b, JavaKind kind, ValueNode x, ValueNode y, IntegerExactOp op) { - BytecodeExceptionKind exceptionKind = kind == JavaKind.Int ? BytecodeExceptionKind.INTEGER_EXACT_OVERFLOW : BytecodeExceptionKind.LONG_EXACT_OVERFLOW; - AbstractBeginNode exceptionEdge = b.genExplicitExceptionEdge(exceptionKind); - if (exceptionEdge != null) { + private static void createIntegerExactOperation(GraphBuilderContext b, JavaKind kind, ValueNode x, ValueNode y, IntegerExactOp op) { + if (b.needsExplicitException()) { + BytecodeExceptionKind exceptionKind = kind == JavaKind.Int ? BytecodeExceptionKind.INTEGER_EXACT_OVERFLOW : BytecodeExceptionKind.LONG_EXACT_OVERFLOW; + AbstractBeginNode exceptionEdge = b.genExplicitExceptionEdge(exceptionKind); IntegerExactArithmeticSplitNode split = b.addPush(kind, createIntegerExactSplit(x, y, exceptionEdge, op)); split.setNext(b.add(new BeginNode())); - return true; + } else { + b.addPush(kind, createIntegerExactArithmeticNode(b, x, y, op)); } - return false; } private static void registerMathPlugins(InvocationPlugins plugins, boolean allowDeoptimization) { @@ -575,12 +635,12 @@ if (allowDeoptimization) { for (JavaKind kind : new JavaKind[]{JavaKind.Int, JavaKind.Long}) { Class type = kind.toJavaClass(); - r.register1("decrementExact", type, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) { ConstantNode y = b.add(ConstantNode.forIntegerKind(kind, 1)); - return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_DECREMENT_EXACT); + createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_DECREMENT_EXACT); + return true; } }); @@ -588,29 +648,31 @@ @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) { ConstantNode y = b.add(ConstantNode.forIntegerKind(kind, 1)); - return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_INCREMENT_EXACT); + createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_INCREMENT_EXACT); + return true; } }); - r.register2("addExact", type, type, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_ADD_EXACT); + createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_ADD_EXACT); + return true; } }); - r.register2("subtractExact", type, type, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_SUBTRACT_EXACT); + createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_SUBTRACT_EXACT); + return true; } }); r.register2("multiplyExact", type, type, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) { - return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_MULTIPLY_EXACT); - } + createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_MULTIPLY_EXACT); + return true; + } }); } } @@ -1100,23 +1162,7 @@ } } - 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 final SpeculationReasonGroup DIRECTIVE_SPECULATIONS = new SpeculationReasonGroup("GraalDirective", BytecodePosition.class); private static void registerGraalDirectivesPlugins(InvocationPlugins plugins) { Registration r = new Registration(plugins, GraalDirectives.class); @@ -1139,9 +1185,9 @@ 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`"); + GraalError.guarantee(b.getGraph().getSpeculationLog() != null, "A speculation log is needed to use `deoptimizeAndInvalidateWithSpeculation`"); BytecodePosition pos = new BytecodePosition(null, b.getMethod(), b.bci()); - DirectiveSpeculationReason reason = new DirectiveSpeculationReason(pos); + SpeculationReason reason = DIRECTIVE_SPECULATIONS.createSpeculationReason(pos); Speculation speculation; if (b.getGraph().getSpeculationLog().maySpeculate(reason)) { speculation = b.getGraph().getSpeculationLog().speculate(reason); @@ -1324,7 +1370,7 @@ b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter)); } else if (falseCount == 0 || trueCount == 0) { boolean expected = falseCount == 0; - LogicNode condition = b.addWithInputs( + LogicNode condition = b.add( IntegerEqualsNode.create(b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, result, b.add(ConstantNode.forBoolean(!expected)), NodeView.DEFAULT)); b.append(new FixedGuardNode(condition, DeoptimizationReason.UnreachedCode, DeoptimizationAction.InvalidateReprofile, true));