changeset 21611:d246f7b59166

Make BytecodeParser more extensible
author Christian Wimmer <christian.wimmer@oracle.com>
date Fri, 29 May 2015 22:49:07 -0700
parents f555efead2f2
children f2a6088ddebc
files graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FullInfopointNode.java
diffstat 3 files changed, 89 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- 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);
         }
     }
 
--- 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<ValueNode, ValueNode> 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() {
--- 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<FullInfopointNode> 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