# HG changeset patch # User Christian Wimmer # Date 1432964947 25200 # Node ID d246f7b5916638abf089b5227e67f0520e618dd9 # Parent f555efead2f2d4c5a7a8b53a6d753a5223bee99e Make BytecodeParser more extensible diff -r f555efead2f2 -r d246f7b59166 graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java Fri May 29 20:43:55 2015 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java Fri May 29 22:49:07 2015 -0700 @@ -411,8 +411,10 @@ genMonitorEnter(methodSynchronizedObject, bci()); } + finishPrepare(lastInstr); + if (graphBuilderConfig.insertNonSafepointDebugInfo() && !parsingIntrinsic()) { - append(createInfoPointNode(InfopointReason.METHOD_START)); + genInfoPointNode(InfopointReason.METHOD_START, null); } currentBlock = blockMap.getStartBlock(); @@ -441,6 +443,14 @@ } } + /** + * Hook for subclasses to modify the graph start instruction or append new instructions to it. + * + * @param startInstr the start instruction of the graph + */ + protected void finishPrepare(FixedWithNextNode startInstr) { + } + protected void cleanupFinalGraph() { GraphUtil.normalizeLoops(graph); @@ -1014,6 +1024,8 @@ } protected void genThrow() { + genInfoPointNode(InfopointReason.LINE_NUMBER, null); + ValueNode exception = frameState.pop(Kind.Object); append(new FixedGuardNode(graph.unique(new IsNullNode(exception)), NullCheckException, InvalidateReprofile, true)); lastInstr.setNext(handleException(exception, bci())); @@ -1582,7 +1594,7 @@ append(new RegisterFinalizerNode(frameState.loadLocal(0, Kind.Object))); } if (graphBuilderConfig.insertNonSafepointDebugInfo() && !parsingIntrinsic()) { - append(createInfoPointNode(InfopointReason.METHOD_END)); + genInfoPointNode(InfopointReason.METHOD_END, x); } synchronizedEpilogue(BytecodeFrame.AFTER_BCI, x, kind); @@ -2062,6 +2074,7 @@ lastInstr = firstInstruction; frameState = getEntryState(block, currentDimension); + frameState.cleanDeletedNodes(); parser.setCurrentFrameState(frameState); currentBlock = block; @@ -2228,7 +2241,7 @@ if (graphBuilderConfig.insertNonSafepointDebugInfo() && !parsingIntrinsic()) { currentLineNumber = lnt != null ? lnt.getLineNumber(bci) : (graphBuilderConfig.insertFullDebugInfo() ? -1 : bci); if (currentLineNumber != previousLineNumber) { - append(createInfoPointNode(InfopointReason.LINE_NUMBER)); + genInfoPointNode(InfopointReason.LINE_NUMBER, null); previousLineNumber = currentLineNumber; } } @@ -2242,7 +2255,7 @@ throw new BailoutException("OSR into a JSR scope is not supported"); } EntryMarkerNode x = append(new EntryMarkerNode()); - frameState.insertProxies(x); + frameState.insertProxies(value -> ProxyNode.forValue(value, x, graph)); x.setStateAfter(createFrameState(bci, x)); } @@ -2301,7 +2314,7 @@ } /** - * A hook for derived classes to modify the last instruction or add other instructions. + * Hook for subclasses to modify the last instruction or add other instructions. * * @param instr The last instruction (= fixed node) which was added. * @param state The current frame state. @@ -2311,20 +2324,21 @@ return instr; } - private InfopointNode createInfoPointNode(InfopointReason reason) { - if (graphBuilderConfig.insertFullDebugInfo()) { - return new FullInfopointNode(reason, createFrameState(bci(), null)); - } else { - BytecodePosition position = createBytecodePosition(); - // Update the previous infopoint position if no new fixed nodes were inserted - if (lastInstr instanceof SimpleInfopointNode) { - SimpleInfopointNode lastInfopoint = (SimpleInfopointNode) lastInstr; - if (lastInfopoint.getReason() == reason) { - lastInfopoint.setPosition(position); - return lastInfopoint; + private void genInfoPointNode(InfopointReason reason, ValueNode escapedReturnValue) { + if (!parsingIntrinsic()) { + if (graphBuilderConfig.insertFullDebugInfo()) { + append(new FullInfopointNode(reason, createFrameState(bci(), null), escapedReturnValue)); + } else { + BytecodePosition position = createBytecodePosition(); + // Update the previous infopoint position if no new fixed nodes were inserted + if (lastInstr instanceof SimpleInfopointNode) { + SimpleInfopointNode lastInfopoint = (SimpleInfopointNode) lastInstr; + if (lastInfopoint.getReason() == reason) { + lastInfopoint.setPosition(position); + } } + append(new SimpleInfopointNode(reason, position)); } - return new SimpleInfopointNode(reason, position); } } diff -r f555efead2f2 -r d246f7b59166 graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Fri May 29 20:43:55 2015 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Fri May 29 22:49:07 2015 -0700 @@ -28,6 +28,7 @@ import static com.oracle.jvmci.common.JVMCIError.*; import java.util.*; +import java.util.function.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graphbuilderconf.IntrinsicContext.SideEffectsState; @@ -213,12 +214,12 @@ } public FrameState create(int bci, StateSplit forStateSplit) { - if (parser.parsingIntrinsic()) { + if (parser != null && parser.parsingIntrinsic()) { return parser.intrinsicContext.createFrameState(parser.getGraph(), this, forStateSplit); } // Skip intrinsic frames - return create(bci, parser.getNonIntrinsicAncestor(), false, null, null); + return create(bci, parser != null ? parser.getNonIntrinsicAncestor() : null, false, null, null); } /** @@ -307,6 +308,29 @@ return true; } + /** + * Phi nodes are recursively deleted in {@link #propagateDelete}. However, this does not cover + * frame state builder objects, since these are not nodes and not in the usage list of the phi + * node. Therefore, we clean the frame state builder manually here, before we parse a block. + */ + public void cleanDeletedNodes() { + for (int i = 0; i < localsSize(); i++) { + ValueNode node = locals[i]; + if (node != null && node.isDeleted()) { + assert node instanceof ValuePhiNode || node instanceof ValueProxyNode; + locals[i] = null; + } + } + for (int i = 0; i < stackSize(); i++) { + ValueNode node = stack[i]; + assert node == null || !node.isDeleted(); + } + for (int i = 0; i < lockedObjects.length; i++) { + ValueNode node = lockedObjects[i]; + assert !node.isDeleted(); + } + } + public void merge(AbstractMergeNode block, FrameStateBuilder other) { assert isCompatibleWith(other); @@ -419,26 +443,26 @@ } } - public void insertProxies(AbstractBeginNode begin) { + public void insertProxies(Function proxyFunction) { for (int i = 0; i < localsSize(); i++) { ValueNode value = locals[i]; if (value != null) { Debug.log(" inserting proxy for %s", value); - locals[i] = ProxyNode.forValue(value, begin, graph); + locals[i] = proxyFunction.apply(value); } } for (int i = 0; i < stackSize(); i++) { ValueNode value = stack[i]; if (value != null) { Debug.log(" inserting proxy for %s", value); - stack[i] = ProxyNode.forValue(value, begin, graph); + stack[i] = proxyFunction.apply(value); } } for (int i = 0; i < lockedObjects.length; i++) { ValueNode value = lockedObjects[i]; if (value != null) { Debug.log(" inserting proxy for %s", value); - lockedObjects[i] = ProxyNode.forValue(value, begin, graph); + lockedObjects[i] = proxyFunction.apply(value); } } } @@ -541,6 +565,15 @@ } /** + * Clears all local variables. + */ + public void clearLocals() { + for (int i = 0; i < locals.length; i++) { + locals[i] = null; + } + } + + /** * @see BytecodeFrame#rethrowException */ public boolean rethrowException() { diff -r f555efead2f2 -r d246f7b59166 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FullInfopointNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FullInfopointNode.java Fri May 29 20:43:55 2015 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FullInfopointNode.java Fri May 29 22:49:07 2015 -0700 @@ -23,6 +23,7 @@ package com.oracle.graal.nodes; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.spi.*; import com.oracle.jvmci.code.*; @@ -31,13 +32,29 @@ * Nodes of this type are inserted into the graph to denote points of interest to debugging. */ @NodeInfo -public final class FullInfopointNode extends InfopointNode implements LIRLowerable, NodeWithState { +public final class FullInfopointNode extends InfopointNode implements LIRLowerable, NodeWithState, Simplifiable { public static final NodeClass TYPE = NodeClass.create(FullInfopointNode.class); @Input(InputType.State) FrameState state; + @OptionalInput ValueNode escapedReturnValue; - public FullInfopointNode(InfopointReason reason, FrameState state) { + public FullInfopointNode(InfopointReason reason, FrameState state, ValueNode escapedReturnValue) { super(TYPE, reason); this.state = state; + this.escapedReturnValue = escapedReturnValue; + } + + private void setEscapedReturnValue(ValueNode x) { + updateUsages(escapedReturnValue, x); + escapedReturnValue = x; + } + + @Override + public void simplify(SimplifierTool tool) { + if (escapedReturnValue != null && state != null && state.outerFrameState() != null) { + ValueNode returnValue = escapedReturnValue; + setEscapedReturnValue(null); + tool.removeIfUnused(returnValue); + } } @Override