--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Fri Feb 02 10:37:48 2018 -0500
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Fri Feb 02 17:28:17 2018 -0800
@@ -265,6 +265,8 @@
import java.util.Formatter;
import java.util.List;
+import org.graalvm.collections.EconomicMap;
+import org.graalvm.collections.Equivalence;
import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.bytecode.Bytecode;
import org.graalvm.compiler.bytecode.BytecodeDisassembler;
@@ -278,9 +280,12 @@
import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecode;
import org.graalvm.compiler.bytecode.ResolvedJavaMethodBytecodeProvider;
import org.graalvm.compiler.core.common.PermanentBailoutException;
+import org.graalvm.compiler.core.common.calc.CanonicalCondition;
import org.graalvm.compiler.core.common.calc.Condition;
+import org.graalvm.compiler.core.common.calc.Condition.CanonicalizedCondition;
import org.graalvm.compiler.core.common.calc.FloatConvert;
import org.graalvm.compiler.core.common.spi.ConstantFieldProvider;
+import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.ObjectStamp;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
@@ -343,8 +348,8 @@
import org.graalvm.compiler.nodes.calc.AndNode;
import org.graalvm.compiler.nodes.calc.CompareNode;
import org.graalvm.compiler.nodes.calc.ConditionalNode;
+import org.graalvm.compiler.nodes.calc.FloatConvertNode;
import org.graalvm.compiler.nodes.calc.FloatDivNode;
-import org.graalvm.compiler.nodes.calc.FloatConvertNode;
import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
@@ -408,8 +413,6 @@
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.OptimisticOptimizations;
import org.graalvm.compiler.phases.util.ValueMergeUtil;
-import org.graalvm.util.EconomicMap;
-import org.graalvm.util.Equivalence;
import org.graalvm.word.LocationIdentity;
import jdk.vm.ci.code.BailoutException;
@@ -436,7 +439,6 @@
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.Signature;
import jdk.vm.ci.meta.TriState;
-import org.graalvm.compiler.core.common.type.IntegerStamp;
/**
* The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph.
@@ -577,10 +579,11 @@
// value on the stack on entry to an exception handler,
// namely the exception object.
assert frameState.rethrowException();
- ExceptionObjectNode exceptionObject = (ExceptionObjectNode) frameState.stackAt(0);
+ ValueNode exceptionValue = frameState.stackAt(0);
+ ExceptionObjectNode exceptionObject = (ExceptionObjectNode) GraphUtil.unproxify(exceptionValue);
FrameStateBuilder dispatchState = parser.frameState.copy();
dispatchState.clearStack();
- dispatchState.push(JavaKind.Object, exceptionObject);
+ dispatchState.push(JavaKind.Object, exceptionValue);
dispatchState.setRethrowException(true);
FrameState newFrameState = dispatchState.create(parser.bci(), exceptionObject);
frameState.replaceAndDelete(newFrameState);
@@ -700,6 +703,12 @@
assert code.getCode() != null : "method must contain bytecodes: " + method;
+ if (TraceBytecodeParserLevel.getValue(options) != 0) {
+ if (!Assertions.assertionsEnabled()) {
+ throw new IllegalArgumentException("A non-zero " + TraceBytecodeParserLevel.getName() + " value requires assertions to be enabled");
+ }
+ }
+
if (graphBuilderConfig.insertFullInfopoints() && !parsingIntrinsic()) {
lnt = code.getLineNumberTable();
previousLineNumber = -1;
@@ -1893,7 +1902,7 @@
LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, nonNullReceiver));
LoadMethodNode actual = append(new LoadMethodNode(methodStamp, targetMethod, receiverType, method.getDeclaringClass(), hub));
ConstantNode expected = graph.unique(ConstantNode.forConstant(methodStamp, targetMethod.getEncoding(), getMetaAccess()));
- LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, Condition.EQ, actual, expected, NodeView.DEFAULT));
+ LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, CanonicalCondition.EQ, actual, expected, NodeView.DEFAULT));
JavaTypeProfile profile = null;
if (profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) {
@@ -2267,8 +2276,10 @@
}
protected void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, IntrinsicContext calleeIntrinsicContext) {
+ FixedWithNextNode calleeBeforeUnwindNode = null;
+ ValueNode calleeUnwindValue = null;
+
try (IntrinsicScope s = calleeIntrinsicContext != null && !parsingIntrinsic() ? new IntrinsicScope(this, targetMethod.getSignature().toParameterKinds(!targetMethod.isStatic()), args) : null) {
-
BytecodeParser parser = graphBuilderInstance.createBytecodeParser(graph, this, targetMethod, INVOCATION_ENTRY_BCI, calleeIntrinsicContext);
FrameStateBuilder startFrameState = new FrameStateBuilder(parser, parser.code, graph);
if (!targetMethod.isStatic()) {
@@ -2315,13 +2326,25 @@
}
}
- FixedWithNextNode calleeBeforeUnwindNode = parser.getBeforeUnwindNode();
+ calleeBeforeUnwindNode = parser.getBeforeUnwindNode();
if (calleeBeforeUnwindNode != null) {
- ValueNode calleeUnwindValue = parser.getUnwindValue();
+ calleeUnwindValue = parser.getUnwindValue();
assert calleeUnwindValue != null;
- calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci(), false));
}
}
+
+ /*
+ * Method handleException will call createTarget, which wires this exception edge to the
+ * corresponding exception dispatch block in the caller. In the case where it wires to the
+ * caller's unwind block, any FrameState created meanwhile, e.g., FrameState for
+ * LoopExitNode, would be instantiated with AFTER_EXCEPTION_BCI. Such frame states should
+ * not be fixed by IntrinsicScope.close, as they denote the states of the caller. Thus, the
+ * following code should be placed outside the IntrinsicScope, so that correctly created
+ * FrameStates are not replaced.
+ */
+ if (calleeBeforeUnwindNode != null) {
+ calleeBeforeUnwindNode.setNext(handleException(calleeUnwindValue, bci(), false));
+ }
}
public MethodCallTargetNode createMethodCallTarget(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args, StampPair returnStamp, JavaTypeProfile profile) {
@@ -2773,6 +2796,10 @@
setCurrentFrameState(frameState);
currentBlock = block;
+ if (block != blockMap.getUnwindBlock() && !(block instanceof ExceptionDispatchBlock)) {
+ frameState.setRethrowException(false);
+ }
+
if (firstInstruction instanceof AbstractMergeNode) {
setMergeStateAfter(block, firstInstruction);
}
@@ -2782,7 +2809,6 @@
} else if (block instanceof ExceptionDispatchBlock) {
createExceptionDispatch((ExceptionDispatchBlock) block);
} else {
- frameState.setRethrowException(false);
iterateBytecodesForBlock(block);
}
}
@@ -3055,7 +3081,7 @@
}
private boolean traceState() {
- if (debug.isLogEnabled() && TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_STATE) {
+ if (TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_STATE) {
frameState.traceState();
}
return true;
@@ -3075,56 +3101,107 @@
ValueNode a = x;
ValueNode b = y;
+ BciBlock trueSuccessor = trueBlock;
+ BciBlock falseSuccessor = falseBlock;
+
+ CanonicalizedCondition canonicalizedCondition = cond.canonicalize();
// Check whether the condition needs to mirror the operands.
- if (cond.canonicalMirror()) {
+ if (canonicalizedCondition.mustMirror()) {
a = y;
b = x;
}
+ if (canonicalizedCondition.mustNegate()) {
+ trueSuccessor = falseBlock;
+ falseSuccessor = trueBlock;
+ }
// Create the logic node for the condition.
- LogicNode condition = createLogicNode(cond, a, b);
-
- // Check whether the condition needs to negate the result.
- boolean negate = cond.canonicalNegate();
- genIf(condition, negate, trueBlock, falseBlock);
- }
-
- protected void genIf(LogicNode conditionInput, boolean negateCondition, BciBlock trueBlockInput, BciBlock falseBlockInput) {
+ LogicNode condition = createLogicNode(canonicalizedCondition.getCanonicalCondition(), a, b);
+
+ double probability = -1;
+ if (condition instanceof IntegerEqualsNode) {
+ probability = extractInjectedProbability((IntegerEqualsNode) condition);
+ // the probability coming from here is about the actual condition
+ }
+
+ if (probability == -1) {
+ probability = getProfileProbability(canonicalizedCondition.mustNegate());
+ }
+
+ probability = clampProbability(probability);
+ genIf(condition, trueSuccessor, falseSuccessor, probability);
+ }
+
+ private double getProfileProbability(boolean negate) {
+ double probability;
+ if (profilingInfo == null) {
+ probability = 0.5;
+ } else {
+ assert assertAtIfBytecode();
+ probability = profilingInfo.getBranchTakenProbability(bci());
+ if (probability < 0) {
+ assert probability == -1 : "invalid probability";
+ debug.log("missing probability in %s at bci %d", code, bci());
+ probability = 0.5;
+ } else {
+ if (negate) {
+ // the probability coming from profile is about the original condition
+ probability = 1 - probability;
+ }
+ }
+ }
+ return probability;
+ }
+
+ private static double extractInjectedProbability(IntegerEqualsNode condition) {
+ // Propagate injected branch probability if any.
+ IntegerEqualsNode equalsNode = condition;
+ BranchProbabilityNode probabilityNode = null;
+ ValueNode other = null;
+ if (equalsNode.getX() instanceof BranchProbabilityNode) {
+ probabilityNode = (BranchProbabilityNode) equalsNode.getX();
+ other = equalsNode.getY();
+ } else if (equalsNode.getY() instanceof BranchProbabilityNode) {
+ probabilityNode = (BranchProbabilityNode) equalsNode.getY();
+ other = equalsNode.getX();
+ }
+
+ if (probabilityNode != null && probabilityNode.getProbability().isConstant() && other != null && other.isConstant()) {
+ double probabilityValue = probabilityNode.getProbability().asJavaConstant().asDouble();
+ return other.asJavaConstant().asInt() == 0 ? 1.0 - probabilityValue : probabilityValue;
+ }
+ return -1;
+ }
+
+ protected void genIf(LogicNode conditionInput, BciBlock trueBlockInput, BciBlock falseBlockInput, double probabilityInput) {
BciBlock trueBlock = trueBlockInput;
BciBlock falseBlock = falseBlockInput;
LogicNode condition = conditionInput;
+ double probability = probabilityInput;
FrameState stateBefore = null;
ProfilingPlugin profilingPlugin = this.graphBuilderConfig.getPlugins().getProfilingPlugin();
if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
stateBefore = frameState.create(bci(), getNonIntrinsicAncestor(), false, null, null);
}
- // Remove a logic negation node and fold it into the negate boolean.
- boolean negate = negateCondition;
+ // Remove a logic negation node.
if (condition instanceof LogicNegationNode) {
LogicNegationNode logicNegationNode = (LogicNegationNode) condition;
- negate = !negate;
+ BciBlock tmpBlock = trueBlock;
+ trueBlock = falseBlock;
+ falseBlock = tmpBlock;
+ probability = 1 - probability;
condition = logicNegationNode.getValue();
}
if (condition instanceof LogicConstantNode) {
- genConstantTargetIf(trueBlock, falseBlock, negate, condition);
+ genConstantTargetIf(trueBlock, falseBlock, condition);
} else {
if (condition.graph() == null) {
condition = genUnique(condition);
}
- // Need to get probability based on current bci.
- double probability = branchProbability(condition);
-
- if (negate) {
- BciBlock tmpBlock = trueBlock;
- trueBlock = falseBlock;
- falseBlock = tmpBlock;
- probability = 1 - probability;
- }
-
if (isNeverExecutedCode(probability)) {
append(new FixedGuardNode(condition, UnreachedCode, InvalidateReprofile, true));
if (profilingPlugin != null && profilingPlugin.shouldProfile(this, method)) {
@@ -3200,28 +3277,26 @@
}
}
- private LogicNode createLogicNode(Condition cond, ValueNode a, ValueNode b) {
- LogicNode condition;
+ private LogicNode createLogicNode(CanonicalCondition cond, ValueNode a, ValueNode b) {
assert !a.getStackKind().isNumericFloat();
- if (cond == Condition.EQ || cond == Condition.NE) {
- if (a.getStackKind() == JavaKind.Object) {
- condition = genObjectEquals(a, b);
- } else {
- condition = genIntegerEquals(a, b);
- }
- } else {
- assert a.getStackKind() != JavaKind.Object && !cond.isUnsigned();
- condition = genIntegerLessThan(a, b);
+ switch (cond) {
+ case EQ:
+ if (a.getStackKind() == JavaKind.Object) {
+ return genObjectEquals(a, b);
+ } else {
+ return genIntegerEquals(a, b);
+ }
+ case LT:
+ assert a.getStackKind() != JavaKind.Object;
+ return genIntegerLessThan(a, b);
+ default:
+ throw GraalError.shouldNotReachHere("Unexpected condition: " + cond);
}
- return condition;
- }
-
- private void genConstantTargetIf(BciBlock trueBlock, BciBlock falseBlock, boolean negate, LogicNode condition) {
+ }
+
+ private void genConstantTargetIf(BciBlock trueBlock, BciBlock falseBlock, LogicNode condition) {
LogicConstantNode constantLogicNode = (LogicConstantNode) condition;
boolean value = constantLogicNode.getValue();
- if (negate) {
- value = !value;
- }
BciBlock nextBlock = falseBlock;
if (value) {
nextBlock = trueBlock;
@@ -3775,7 +3850,13 @@
BciBlock firstSucc = currentBlock.getSuccessor(0);
BciBlock secondSucc = currentBlock.getSuccessor(1);
if (firstSucc != secondSucc) {
- genIf(instanceOfNode, value != Bytecodes.IFNE, firstSucc, secondSucc);
+ boolean negate = value != Bytecodes.IFNE;
+ if (negate) {
+ BciBlock tmp = firstSucc;
+ firstSucc = secondSucc;
+ secondSucc = tmp;
+ }
+ genIf(instanceOfNode, firstSucc, secondSucc, getProfileProbability(negate));
} else {
appendGoto(firstSucc);
}
@@ -4263,47 +4344,12 @@
return probability == 0 && optimisticOpts.removeNeverExecutedCode(getOptions());
}
- private double rawBranchProbability(LogicNode conditionInput) {
- if (conditionInput instanceof IntegerEqualsNode) {
- // Propagate injected branch probability if any.
- IntegerEqualsNode condition = (IntegerEqualsNode) conditionInput;
- BranchProbabilityNode injectedProbability = null;
- ValueNode other = null;
- if (condition.getX() instanceof BranchProbabilityNode) {
- injectedProbability = (BranchProbabilityNode) condition.getX();
- other = condition.getY();
- } else if (condition.getY() instanceof BranchProbabilityNode) {
- injectedProbability = (BranchProbabilityNode) condition.getY();
- other = condition.getX();
- }
-
- if (injectedProbability != null && injectedProbability.getProbability().isConstant() && other != null && other.isConstant()) {
- double probabilityValue = injectedProbability.getProbability().asJavaConstant().asDouble();
- return other.asJavaConstant().asInt() == 0 ? 1.0 - probabilityValue : probabilityValue;
- }
- }
-
- if (profilingInfo == null) {
- return 0.5;
- }
- assert assertAtIfBytecode();
-
- return profilingInfo.getBranchTakenProbability(bci());
- }
-
- protected double branchProbability(LogicNode conditionInput) {
- double probability = rawBranchProbability(conditionInput);
- if (probability < 0) {
- assert probability == -1 : "invalid probability";
- debug.log("missing probability in %s at bci %d", code, bci());
- probability = 0.5;
- }
-
+ private double clampProbability(double probability) {
if (!optimisticOpts.removeNeverExecutedCode(getOptions())) {
if (probability == 0) {
- probability = 0.0000001;
+ return 0.0000001;
} else if (probability == 1) {
- probability = 0.999999;
+ return 0.999999;
}
}
return probability;
@@ -4568,7 +4614,7 @@
}
protected boolean traceInstruction(int bci, int opcode, boolean blockStart) {
- if (debug.isLogEnabled() && TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_INSTRUCTIONS) {
+ if (TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_INSTRUCTIONS) {
traceInstructionHelper(bci, opcode, blockStart);
}
return true;
@@ -4589,7 +4635,7 @@
if (!currentBlock.getJsrScope().isEmpty()) {
sb.append(' ').append(currentBlock.getJsrScope());
}
- debug.log("%s", sb);
+ TTY.println("%s", sb);
}
@Override