changeset 12623:0d6ad1cd4191

documentation and simplification in MonitorExitNode
author Lukas Stadler <lukas.stadler@jku.at>
date Mon, 28 Oct 2013 15:27:05 +0100
parents f40b8d0d9dcb
children 37a4252fbcc7
files graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java
diffstat 1 files changed, 23 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Mon Oct 28 15:25:27 2013 +0100
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Mon Oct 28 15:27:05 2013 +0100
@@ -24,22 +24,24 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 
 /**
- * The {@code MonitorEnterNode} represents a monitor release.
+ * 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.
  */
-public final class MonitorExitNode extends AccessMonitorNode implements Virtualizable, Lowerable, IterableNodeType, MonitorExit, MemoryCheckpoint.Single, MonitorReference {
+public final class MonitorExitNode extends AccessMonitorNode implements Virtualizable, Simplifiable, Lowerable, IterableNodeType, MonitorExit, MemoryCheckpoint.Single, MonitorReference {
+
+    @Input private ValueNode escapedReturnValue;
 
     private int lockDepth;
-    @Input private ValueNode escapedReturnValue;
 
     /**
      * Creates a new MonitorExitNode.
-     * 
-     * @param object the instruction produces the object value
      */
     public MonitorExitNode(ValueNode object, ValueNode escapedReturnValue, int lockDepth) {
         super(object);
@@ -58,6 +60,15 @@
     }
 
     @Override
+    public void simplify(SimplifierTool tool) {
+        if (escapedReturnValue != null && stateAfter().bci != FrameState.AFTER_BCI) {
+            ValueNode returnValue = escapedReturnValue;
+            setEscapedReturnValue(null);
+            tool.removeIfUnused(returnValue);
+        }
+    }
+
+    @Override
     public void lower(LoweringTool tool) {
         tool.getLowerer().lower(this, tool);
     }
@@ -72,20 +83,13 @@
 
     @Override
     public void virtualize(VirtualizerTool tool) {
-        /*
-         * The last MonitorExitNode of a synchronized method cannot be removed anyway, and we need
-         * it to materialize the return value.
-         * 
-         * TODO: replace this with correct handling of AFTER_BCI frame states in the runtime.
-         */
-        if (stateAfter().bci != FrameState.AFTER_BCI) {
-            setEscapedReturnValue(null);
-            State state = tool.getObjectState(object());
-            if (state != null && state.getState() == EscapeState.Virtual && state.getVirtualObject().hasIdentity()) {
-                int removedLock = state.removeLock();
-                assert removedLock == getLockDepth();
-                tool.delete();
-            }
+        State state = tool.getObjectState(object());
+        // the monitor exit for a synchronized method should never be virtualized
+        assert stateAfter().bci != FrameState.AFTER_BCI || state == null;
+        if (state != null && state.getState() == EscapeState.Virtual && state.getVirtualObject().hasIdentity()) {
+            int removedLock = state.removeLock();
+            assert removedLock == getLockDepth();
+            tool.delete();
         }
     }
 }