--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Fri Jul 07 10:37:52 2017 +0200
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java Fri Jul 07 09:40:47 2017 -0700
@@ -27,6 +27,8 @@
import static java.lang.reflect.Modifier.SYNCHRONIZED;
import static jdk.vm.ci.meta.DeoptimizationAction.InvalidateRecompile;
import static jdk.vm.ci.meta.DeoptimizationAction.InvalidateReprofile;
+import static jdk.vm.ci.meta.DeoptimizationAction.None;
+import static jdk.vm.ci.meta.DeoptimizationReason.ClassCastException;
import static jdk.vm.ci.meta.DeoptimizationReason.JavaSubroutineMismatch;
import static jdk.vm.ci.meta.DeoptimizationReason.NullCheckException;
import static jdk.vm.ci.meta.DeoptimizationReason.RuntimeConstraint;
@@ -286,10 +288,9 @@
import org.graalvm.compiler.core.common.type.TypeReference;
import org.graalvm.compiler.core.common.util.Util;
import org.graalvm.compiler.debug.Assertions;
-import org.graalvm.compiler.debug.Debug;
-import org.graalvm.compiler.debug.Debug.Scope;
+import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugCloseable;
-import org.graalvm.compiler.debug.DebugCounter;
+import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.debug.Indent;
import org.graalvm.compiler.debug.TTY;
@@ -452,9 +453,9 @@
/**
* Meters the number of actual bytecodes parsed.
*/
- public static final DebugCounter BytecodesParsed = Debug.counter("BytecodesParsed");
-
- protected static final DebugCounter EXPLICIT_EXCEPTIONS = Debug.counter("ExplicitExceptions");
+ public static final CounterKey BytecodesParsed = DebugContext.counter("BytecodesParsed");
+
+ protected static final CounterKey EXPLICIT_EXCEPTIONS = DebugContext.counter("ExplicitExceptions");
/**
* A scoped object for tasks to be performed after parsing an intrinsic such as processing
@@ -629,6 +630,7 @@
private final GraphBuilderPhase.Instance graphBuilderInstance;
protected final StructuredGraph graph;
protected final OptionValues options;
+ protected final DebugContext debug;
private BciBlockMapping blockMap;
private LocalLiveness liveness;
@@ -663,6 +665,7 @@
this.graphBuilderInstance = graphBuilderInstance;
this.graph = graph;
this.options = graph.getOptions();
+ this.debug = graph.getDebug();
this.graphBuilderConfig = graphBuilderInstance.graphBuilderConfig;
this.optimisticOpts = graphBuilderInstance.optimisticOpts;
this.metaAccess = graphBuilderInstance.metaAccess;
@@ -716,7 +719,7 @@
TTY.println(Util.indent(profilingInfo.toString(method, CodeUtil.NEW_LINE), " "));
}
- try (Indent indent = Debug.logAndIndent("build graph for %s", method)) {
+ try (Indent indent = debug.logAndIndent("build graph for %s", method)) {
if (bytecodeProvider.shouldRecordMethodDependencies()) {
assert getParent() != null || method.equals(graph.method());
// Record method dependency in the graph
@@ -724,7 +727,7 @@
}
// compute the block map, setup exception handlers and get the entrypoint(s)
- BciBlockMapping newMapping = BciBlockMapping.create(stream, code, options);
+ BciBlockMapping newMapping = BciBlockMapping.create(stream, code, options, graph.getDebug());
this.blockMap = newMapping;
this.firstInstructionArray = new FixedWithNextNode[blockMap.getBlockCount()];
this.entryStateArray = new FrameStateBuilder[blockMap.getBlockCount()];
@@ -738,11 +741,11 @@
*/
assert computeKindVerification(startFrameState);
- try (Scope s = Debug.scope("LivenessAnalysis")) {
+ try (DebugContext.Scope s = debug.scope("LivenessAnalysis")) {
int maxLocals = method.getMaxLocals();
- liveness = LocalLiveness.compute(stream, blockMap.getBlocks(), maxLocals, blockMap.getLoopCount());
+ liveness = LocalLiveness.compute(debug, stream, blockMap.getBlocks(), maxLocals, blockMap.getLoopCount());
} catch (Throwable e) {
- throw Debug.handle(e);
+ throw debug.handle(e);
}
lastInstr = startInstruction;
@@ -1005,7 +1008,7 @@
private AbstractBeginNode handleException(ValueNode exceptionObject, int bci) {
assert bci == BytecodeFrame.BEFORE_BCI || bci == bci() : "invalid bci";
- Debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, (profilingInfo == null ? "" : profilingInfo.getExceptionSeen(bci)));
+ debug.log("Creating exception dispatch edges at %d, exception object=%s, exception seen=%s", bci, exceptionObject, (profilingInfo == null ? "" : profilingInfo.getExceptionSeen(bci)));
FrameStateBuilder dispatchState = frameState.copy();
dispatchState.clearStack();
@@ -1244,7 +1247,7 @@
exception.setStateAfter(createFrameState(bci(), exception));
exception.setNext(handleException(exception, bci()));
- EXPLICIT_EXCEPTIONS.increment();
+ EXPLICIT_EXCEPTIONS.increment(debug);
return nonNullReceiver;
}
@@ -1452,6 +1455,10 @@
args[0] = emitExplicitExceptions(args[0]);
}
+ if (initialInvokeKind == InvokeKind.Special && !targetMethod.isConstructor()) {
+ emitCheckForInvokeSuperSpecial(args);
+ }
+
InlineInfo inlineInfo = null;
try {
currentInvoke = new CurrentInvoke(args, invokeKind, returnType);
@@ -1535,6 +1542,30 @@
return invoke;
}
+ /**
+ * Checks that the class of the receiver of an {@link Bytecodes#INVOKESPECIAL} in a method
+ * declared in an interface (i.e., a default method) is assignable to the interface. If not,
+ * then deoptimize so that the interpreter can throw an {@link IllegalAccessError}.
+ *
+ * This is a check not performed by the verifier and so must be performed at runtime.
+ *
+ * @param args arguments to an {@link Bytecodes#INVOKESPECIAL} implementing a direct call to a
+ * method in a super class
+ */
+ protected void emitCheckForInvokeSuperSpecial(ValueNode[] args) {
+ ResolvedJavaType callingClass = method.getDeclaringClass();
+ if (callingClass.getHostClass() != null) {
+ callingClass = callingClass.getHostClass();
+ }
+ if (callingClass.isInterface()) {
+ ValueNode receiver = args[0];
+ TypeReference checkedType = TypeReference.createTrusted(graph.getAssumptions(), callingClass);
+ LogicNode condition = genUnique(createInstanceOf(checkedType, receiver, null));
+ FixedGuardNode fixedGuard = append(new FixedGuardNode(condition, ClassCastException, None, false));
+ args[0] = append(PiNode.create(receiver, StampFactory.object(checkedType, true), fixedGuard));
+ }
+ }
+
protected JavaTypeProfile getProfileForInvoke(InvokeKind invokeKind) {
if (invokeKind.isIndirect() && profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) {
return profilingInfo.getTypeProfile(bci());
@@ -2095,9 +2126,6 @@
StackTraceElement where = code.asStackTraceElement(bci());
String s = format("%s%s (%s:%d) %s", nSpaces(getDepth()), method.isConstructor() ? method.format("%h.%n") : method.getName(), where.getFileName(), where.getLineNumber(),
format(format, args));
- if (s.equals("decrypt (CipherBlockChainingSubstitutions.java:117) inlining call to CipherBlockChainingSubstitutions.decrypt(Object, byte[], int, int, byte[], int)")) {
- System.console();
- }
TTY.println(s);
}
@@ -2421,7 +2449,7 @@
firstLoopExit = loopExit;
}
lastLoopExit = loopExit;
- Debug.log("Target %s Exits %s, scanning framestates...", targetBlock, loop);
+ debug.log("Target %s Exits %s, scanning framestates...", targetBlock, loop);
newState.clearNonLiveLocals(targetBlock, liveness, true);
newState.insertLoopProxies(loopExit, getEntryState(loop));
loopExit.setStateAfter(newState.create(bci, loopExit));
@@ -2487,7 +2515,7 @@
setEntryState(block, currentEntryState);
currentEntryState.clearNonLiveLocals(block, liveness, true);
- Debug.log("createTarget %s: first visit, result: %s", block, targetNode);
+ debug.log("createTarget %s: first visit, result: %s", block, targetNode);
return result;
}
@@ -2508,7 +2536,7 @@
FixedNode result = target.fixed;
getEntryState(block).merge(loopBegin, target.state);
- Debug.log("createTarget %s: merging backward branch to loop header %s, result: %s", block, loopBegin, result);
+ debug.log("createTarget %s: merging backward branch to loop header %s, result: %s", block, loopBegin, result);
return result;
}
assert currentBlock == null || currentBlock.getId() < block.getId() : "must not be backward branch";
@@ -2549,7 +2577,7 @@
getEntryState(block).merge(mergeNode, target.state);
mergeNode.addForwardEnd(newEnd);
- Debug.log("createTarget %s: merging state, result: %s", block, result);
+ debug.log("createTarget %s: merging state, result: %s", block, result);
return result;
}
@@ -2580,10 +2608,10 @@
// Ignore blocks that have no predecessors by the time their bytecodes are parsed
FixedWithNextNode firstInstruction = getFirstInstruction(block);
if (firstInstruction == null) {
- Debug.log("Ignoring block %s", block);
+ debug.log("Ignoring block %s", block);
return;
}
- try (Indent indent = Debug.logAndIndent("Parsing block %s firstInstruction: %s loopHeader: %b", block, firstInstruction, block.isLoopHeader)) {
+ try (Indent indent = debug.logAndIndent("Parsing block %s firstInstruction: %s loopHeader: %b", block, firstInstruction, block.isLoopHeader)) {
lastInstr = firstInstruction;
frameState = getEntryState(block);
@@ -2729,7 +2757,7 @@
*/
setEntryState(block, frameState.copy());
- Debug.log(" created loop header %s", loopBegin);
+ debug.log(" created loop header %s", loopBegin);
} else if (lastInstr instanceof MergeNode) {
/*
* All inputs of non-loop phi nodes are known by now. We can infer the stamp for the
@@ -2738,7 +2766,7 @@
frameState.inferPhiStamps((AbstractMergeNode) lastInstr);
}
assert lastInstr.next() == null : "instructions already appended at block " + block;
- Debug.log(" frameState: %s", frameState);
+ debug.log(" frameState: %s", frameState);
lastInstr = finishInstruction(lastInstr, frameState);
@@ -2746,7 +2774,7 @@
stream.setBCI(block.startBci);
int bci = block.startBci;
- BytecodesParsed.add(block.endBci - bci);
+ BytecodesParsed.add(debug, block.endBci - bci);
/* Reset line number for new block */
if (graphBuilderConfig.insertFullInfopoints()) {
@@ -2807,7 +2835,7 @@
}
private DebugCloseable openNodeContext() {
- if ((graphBuilderConfig.trackNodeSourcePosition() || Debug.isDumpEnabledForMethod()) && !parsingIntrinsic()) {
+ if ((graphBuilderConfig.trackNodeSourcePosition() || debug.isDumpEnabledForMethod()) && !parsingIntrinsic()) {
return graph.withNodeSourcePosition(createBytecodePosition());
}
return null;
@@ -2870,7 +2898,7 @@
}
private boolean traceState() {
- if (Debug.isEnabled() && TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_STATE && Debug.isLogEnabled()) {
+ if (debug.isLogEnabled() && TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_STATE) {
frameState.traceState();
}
return true;
@@ -3920,7 +3948,7 @@
if (prob != null) {
assert prob.length == numberOfCases;
} else {
- Debug.log("Missing probability (switch) in %s at bci %d", method, bci);
+ debug.log("Missing probability (switch) in %s at bci %d", method, bci);
prob = new double[numberOfCases];
for (int i = 0; i < numberOfCases; i++) {
prob[i] = 1.0d / numberOfCases;
@@ -4006,7 +4034,7 @@
double probability = profilingInfo.getBranchTakenProbability(bci());
if (probability < 0) {
assert probability == -1 : "invalid probability";
- Debug.log("missing probability in %s at bci %d", code, bci());
+ debug.log("missing probability in %s at bci %d", code, bci());
probability = 0.5;
}
@@ -4279,7 +4307,7 @@
}
protected boolean traceInstruction(int bci, int opcode, boolean blockStart) {
- if (Debug.isEnabled() && TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_INSTRUCTIONS && Debug.isLogEnabled()) {
+ if (debug.isLogEnabled() && TraceBytecodeParserLevel.getValue(options) >= TRACELEVEL_INSTRUCTIONS) {
traceInstructionHelper(bci, opcode, blockStart);
}
return true;
@@ -4300,7 +4328,7 @@
if (!currentBlock.getJsrScope().isEmpty()) {
sb.append(' ').append(currentBlock.getJsrScope());
}
- Debug.log("%s", sb);
+ debug.log("%s", sb);
}
@Override