< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java
Print this page
@@ -31,12 +31,12 @@
import static jdk.vm.ci.code.MemoryBarriers.LOAD_LOAD;
import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE;
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;
import java.util.Arrays;
@@ -52,22 +52,21 @@
import org.graalvm.compiler.core.common.type.TypeReference;
import org.graalvm.compiler.debug.GraalError;
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;
import org.graalvm.compiler.nodes.DeoptimizeNode;
import org.graalvm.compiler.nodes.EndNode;
import org.graalvm.compiler.nodes.FixedGuardNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
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;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.ValuePhiNode;
@@ -91,10 +90,13 @@
import org.graalvm.compiler.nodes.debug.SpillRegistersNode;
import org.graalvm.compiler.nodes.extended.BoxNode;
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;
import org.graalvm.compiler.nodes.extended.RawStoreNode;
import org.graalvm.compiler.nodes.extended.UnboxNode;
@@ -111,24 +113,29 @@
import org.graalvm.compiler.nodes.java.InstanceOfDynamicNode;
import org.graalvm.compiler.nodes.java.LoadFieldNode;
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;
import org.graalvm.compiler.replacements.nodes.ProfileBooleanNode;
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;
import jdk.vm.ci.meta.DeoptimizationAction;
import jdk.vm.ci.meta.DeoptimizationReason;
@@ -195,12 +202,14 @@
r.register1("hashCode", Receiver.class, new InvocationPlugin() {
@Override
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;
}
});
@@ -219,16 +228,36 @@
return true;
}
});
} 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() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
@@ -527,20 +556,51 @@
return true;
}
});
}
- 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.");
}
}
@@ -557,62 +617,64 @@
default:
throw GraalError.shouldNotReachHere("Unknown integer exact operation.");
}
}
- 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) {
Registration r = new Registration(plugins, Math.class);
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;
}
});
r.register1("incrementExact", 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_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;
+ }
});
}
}
r.register1("abs", Float.TYPE, new InvocationPlugin() {
@@ -1098,27 +1160,11 @@
b.add(new MembarNode(barriers));
return true;
}
}
- 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);
r.register0("deoptimize", new InvocationPlugin() {
@Override
@@ -1137,13 +1183,13 @@
});
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);
} else {
speculation = SpeculationLog.NO_SPECULATION;
@@ -1322,11 +1368,11 @@
if (totalCount == 0) {
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));
newResult = b.add(ConstantNode.forBoolean(expected));
} else {
< prev index next >