changeset 23174:009b2ed708fd

Move handling of MonitorExitNode#escapedReturnValue from the node's simplification procedure to the inlining utility.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Mon, 14 Dec 2015 13:02:35 +0100
parents ccca06a06894
children 1c5c04b9aaf1
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java
diffstat 2 files changed, 24 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Mon Dec 14 12:46:19 2015 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Mon Dec 14 13:02:35 2015 +0100
@@ -22,13 +22,10 @@
  */
 package com.oracle.graal.nodes.java;
 
-import jdk.vm.ci.code.BytecodeFrame;
 import jdk.vm.ci.meta.LocationIdentity;
 
 import com.oracle.graal.graph.IterableNodeType;
 import com.oracle.graal.graph.NodeClass;
-import com.oracle.graal.graph.spi.Simplifiable;
-import com.oracle.graal.graph.spi.SimplifierTool;
 import com.oracle.graal.nodeinfo.NodeInfo;
 import com.oracle.graal.nodes.ValueNode;
 import com.oracle.graal.nodes.extended.MonitorExit;
@@ -41,13 +38,18 @@
 
 /**
  * The {@code MonitorExitNode} represents a monitor release. If it is the release of the monitor of
- * a synchronized method, then the return value of the method will be referenced, so that it will be
- * materialized before releasing the monitor.
+ * a synchronized method, then the return value of the method will be referenced via the edge
+ * {@link #escapedReturnValue}, so that it will be materialized before releasing the monitor.
  */
 @NodeInfo
-public final class MonitorExitNode extends AccessMonitorNode implements Virtualizable, Simplifiable, Lowerable, IterableNodeType, MonitorExit, MemoryCheckpoint.Single {
+public final class MonitorExitNode extends AccessMonitorNode implements Virtualizable, Lowerable, IterableNodeType, MonitorExit, MemoryCheckpoint.Single {
 
     public static final NodeClass<MonitorExitNode> TYPE = NodeClass.create(MonitorExitNode.class);
+
+    /**
+     * Non-null for the monitor exit introduced due to a synchronized root method and null in all
+     * other cases.
+     */
     @OptionalInput ValueNode escapedReturnValue;
 
     public MonitorExitNode(ValueNode object, MonitorIdNode monitorId, ValueNode escapedReturnValue) {
@@ -55,13 +57,12 @@
         this.escapedReturnValue = escapedReturnValue;
     }
 
-    public ValueNode getEscapedReturnValue() {
-        return escapedReturnValue;
-    }
-
-    public void setEscapedReturnValue(ValueNode x) {
-        updateUsages(escapedReturnValue, x);
-        this.escapedReturnValue = x;
+    /**
+     * Return value is cleared when a synchronized method graph is inlined.
+     */
+    public void clearEscapedReturnValue() {
+        updateUsages(escapedReturnValue, null);
+        this.escapedReturnValue = null;
     }
 
     @Override
@@ -70,22 +71,12 @@
     }
 
     @Override
-    public void simplify(SimplifierTool tool) {
-        if (escapedReturnValue != null && stateAfter() != null && stateAfter().bci != BytecodeFrame.AFTER_BCI) {
-            ValueNode returnValue = escapedReturnValue;
-            setEscapedReturnValue(null);
-            tool.removeIfUnused(returnValue);
-        }
-    }
-
-    @Override
     public void lower(LoweringTool tool) {
         tool.getLowerer().lower(this, tool);
     }
 
     @Override
     public void virtualize(VirtualizerTool tool) {
-        // the monitor exit for a synchronized method should never be virtualized
         ValueNode alias = tool.getAlias(object());
         if (alias instanceof VirtualObjectNode) {
             VirtualObjectNode virtual = (VirtualObjectNode) alias;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Mon Dec 14 12:46:19 2015 +0100
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java	Mon Dec 14 13:02:35 2015 +0100
@@ -92,6 +92,7 @@
 import com.oracle.graal.nodes.extended.GuardingNode;
 import com.oracle.graal.nodes.java.ExceptionObjectNode;
 import com.oracle.graal.nodes.java.MethodCallTargetNode;
+import com.oracle.graal.nodes.java.MonitorExitNode;
 import com.oracle.graal.nodes.java.MonitorIdNode;
 import com.oracle.graal.nodes.spi.Replacements;
 import com.oracle.graal.nodes.type.StampTool;
@@ -544,21 +545,22 @@
                 }
             }
 
-            /*
-             * pop return kind from invoke's stateAfter and replace with this frameState's return
-             * value (top of stack)
-             */
+            // pop return kind from invoke's stateAfter and replace with this frameState's return
+            // value (top of stack)
             if (frameState.stackSize() > 0 && (alwaysDuplicateStateAfter || stateAfterReturn.stackAt(0) != frameState.stackAt(0))) {
                 stateAfterReturn = stateAtReturn.duplicateModified(invokeReturnKind, invokeReturnKind, frameState.stackAt(0));
             }
 
+            // Return value does no longer need to be limited by the monitor exit.
+            for (MonitorExitNode n : frameState.usages().filter(MonitorExitNode.class)) {
+                n.clearEscapedReturnValue();
+            }
+
             frameState.replaceAndDelete(stateAfterReturn);
             return stateAfterReturn;
         } else if (stateAtExceptionEdge != null && isStateAfterException(frameState)) {
-            /*
-             * pop exception object from invoke's stateAfter and replace with this frameState's
-             * exception object (top of stack)
-             */
+            // pop exception object from invoke's stateAfter and replace with this frameState's
+            // exception object (top of stack)
             FrameState stateAfterException = stateAtExceptionEdge;
             if (frameState.stackSize() > 0 && stateAtExceptionEdge.stackAt(0) != frameState.stackAt(0)) {
                 stateAfterException = stateAtExceptionEdge.duplicateModified(JavaKind.Object, JavaKind.Object, frameState.stackAt(0));