changeset 19359:afe80ca4b0f0

cache EscapeObjectStates during PEA
author Lukas Stadler <lukas.stadler@oracle.com>
date Fri, 13 Feb 2015 17:42:58 +0100
parents 5ea169a3bf81
children 4d9ff841882c 413ac504d74e
files graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java
diffstat 3 files changed, 58 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java	Fri Feb 13 17:44:27 2015 +0100
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java	Fri Feb 13 17:42:58 2015 +0100
@@ -108,14 +108,14 @@
         add("add virtual mapping", new Effect() {
             @Override
             public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) {
-                assert node.isAlive() && !state.isAlive() && !state.isDeleted();
+                assert node.isAlive() && !state.isDeleted();
                 FrameState stateAfter = node;
                 for (int i = 0; i < stateAfter.virtualObjectMappingCount(); i++) {
                     if (stateAfter.virtualObjectMappingAt(i).object() == state.object()) {
                         stateAfter.virtualObjectMappings().remove(i);
                     }
                 }
-                stateAfter.addVirtualObjectMapping(graph.unique(state));
+                stateAfter.addVirtualObjectMapping(state.isAlive() ? state : graph.unique(state));
             }
 
             @Override
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java	Fri Feb 13 17:44:27 2015 +0100
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java	Fri Feb 13 17:42:58 2015 +0100
@@ -24,11 +24,13 @@
 
 import java.util.*;
 
+import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.spi.Virtualizable.EscapeState;
 import com.oracle.graal.nodes.virtual.*;
+import com.oracle.graal.virtual.nodes.*;
 
 /**
  * This class describes the state of a virtual object while iterating over the graph. It describes
@@ -37,6 +39,9 @@
  */
 public class ObjectState extends Virtualizable.State {
 
+    public static final DebugMetric CREATE_ESCAPED_OBJECT_STATE = Debug.metric("CreateEscapeObjectState");
+    public static final DebugMetric GET_ESCAPED_OBJECT_STATE = Debug.metric("GetEscapeObjectState");
+
     final VirtualObjectNode virtual;
 
     private EscapeState state;
@@ -44,6 +49,8 @@
     private ValueNode materializedValue;
     private LockState locks;
 
+    private EscapeObjectState cachedState;
+
     public ObjectState(VirtualObjectNode virtual, ValueNode[] entries, EscapeState state, List<MonitorIdNode> locks) {
         this(virtual, entries, state, (LockState) null);
         for (int i = locks.size() - 1; i >= 0; i--) {
@@ -71,12 +78,23 @@
         materializedValue = other.materializedValue;
         locks = other.locks;
         state = other.state;
+        cachedState = other.cachedState;
     }
 
     public ObjectState cloneState() {
         return new ObjectState(this);
     }
 
+    public EscapeObjectState createEscapeObjectState() {
+        GET_ESCAPED_OBJECT_STATE.increment();
+        if (cachedState == null) {
+            CREATE_ESCAPED_OBJECT_STATE.increment();
+            cachedState = isVirtual() ? new VirtualObjectState(virtual, entries) : new MaterializedObjectState(virtual, materializedValue);
+        }
+        return cachedState;
+
+    }
+
     @Override
     public EscapeState getState() {
         return state;
@@ -104,7 +122,10 @@
 
     public void setEntry(int index, ValueNode value) {
         assert isVirtual();
-        entries[index] = value;
+        if (entries[index] != value) {
+            cachedState = null;
+            entries[index] = value;
+        }
     }
 
     public void escape(ValueNode materialized, EscapeState newState) {
@@ -112,6 +133,7 @@
         state = newState;
         materializedValue = materialized;
         entries = null;
+        cachedState = null;
         assert !isVirtual();
     }
 
@@ -123,7 +145,10 @@
 
     public void updateMaterializedValue(ValueNode value) {
         assert !isVirtual();
-        materializedValue = value;
+        if (value != materializedValue) {
+            cachedState = null;
+            materializedValue = value;
+        }
     }
 
     @Override
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Fri Feb 13 17:44:27 2015 +0100
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Fri Feb 13 17:42:58 2015 +0100
@@ -38,7 +38,6 @@
 import com.oracle.graal.nodes.spi.Virtualizable.EscapeState;
 import com.oracle.graal.nodes.virtual.*;
 import com.oracle.graal.phases.schedule.*;
-import com.oracle.graal.virtual.nodes.*;
 
 public abstract class PartialEscapeClosure<BlockT extends PartialEscapeBlockState<BlockT>> extends EffectsClosure<BlockT> {
 
@@ -162,7 +161,7 @@
             frameState.applyToNonVirtual(new CollectVirtualObjectsClosure(virtual, effects, state));
             collectLockedVirtualObjects(state, virtual);
             collectReferencedVirtualObjects(state, virtual);
-            addVirtualMappings(state, effects, frameState, virtual);
+            addVirtualMappings(effects, frameState, virtual);
         }
     }
 
@@ -176,15 +175,9 @@
         return frameState;
     }
 
-    private void addVirtualMappings(final BlockT state, final GraphEffectList effects, FrameState frameState, Set<ObjectState> virtual) {
+    private static void addVirtualMappings(GraphEffectList effects, FrameState frameState, Set<ObjectState> virtual) {
         for (ObjectState obj : virtual) {
-            EscapeObjectState v;
-            if (obj.isVirtual()) {
-                v = createVirtualObjectState(state, obj);
-            } else {
-                v = new MaterializedObjectState(obj.virtual, obj.getMaterializedValue());
-            }
-            effects.addVirtualMapping(frameState, v);
+            effects.addVirtualMapping(frameState, obj.createEscapeObjectState());
         }
     }
 
@@ -206,24 +199,7 @@
         }
     }
 
-    private EscapeObjectState createVirtualObjectState(final BlockT state, ObjectState obj) {
-        EscapeObjectState v;
-        ValueNode[] fieldState = obj.getEntries().clone();
-        for (int i = 0; i < fieldState.length; i++) {
-            ObjectState valueObj = getObjectState(state, fieldState[i]);
-            if (valueObj != null) {
-                if (valueObj.isVirtual()) {
-                    fieldState[i] = valueObj.virtual;
-                } else {
-                    fieldState[i] = valueObj.getMaterializedValue();
-                }
-            }
-        }
-        v = new VirtualObjectState(obj.virtual, fieldState);
-        return v;
-    }
-
-    private void collectLockedVirtualObjects(final BlockT state, final Set<ObjectState> virtual) {
+    private void collectLockedVirtualObjects(final BlockT state, Set<ObjectState> virtual) {
         for (ObjectState obj : state.getStates()) {
             if (obj.isVirtual() && obj.hasLocks()) {
                 virtual.add(obj);
@@ -239,6 +215,7 @@
         if (obj.getState() == EscapeState.Virtual) {
             metric.increment();
             state.materializeBefore(materializeBefore, obj.virtual, EscapeState.Materialized, effects);
+            updateStatesForMaterialized(state, obj);
             assert !obj.isVirtual();
             return true;
         } else {
@@ -247,6 +224,20 @@
         }
     }
 
+    private static void updateStatesForMaterialized(PartialEscapeBlockState<?> state, ObjectState obj) {
+        // update all existing states with the newly materialized object
+        for (ObjectState objState : state.objectStates.values()) {
+            if (objState.isVirtual()) {
+                ValueNode[] entries = objState.getEntries();
+                for (int i = 0; i < entries.length; i++) {
+                    if (entries[i] == obj.virtual) {
+                        objState.setEntry(i, obj.getMaterializedValue());
+                    }
+                }
+            }
+        }
+    }
+
     private boolean replaceWithMaterialized(Node value, Node usage, FixedNode materializeBefore, BlockT state, ObjectState obj, GraphEffectList effects, DebugMetric metric) {
         boolean materialized = ensureMaterialized(state, obj, materializeBefore, effects, metric);
         effects.replaceFirstInput(usage, value, obj.getMaterializedValue());
@@ -538,8 +529,8 @@
                 int valueIndex = 0;
                 while (valueIndex < values.length) {
                     for (int i = 1; i < objStates.length; i++) {
-                        ValueNode[] fields = objStates[i].getEntries();
-                        if (phis[valueIndex] == null && values[valueIndex] != fields[valueIndex]) {
+                        ValueNode field = objStates[i].getEntry(valueIndex);
+                        if (phis[valueIndex] == null && values[valueIndex] != field) {
                             phis[valueIndex] = new ValuePhiNode(values[valueIndex].stamp().unrestricted(), merge);
                         }
                     }
@@ -596,14 +587,16 @@
                 if (!objStates[i].isVirtual()) {
                     break;
                 }
-                ValueNode[] entries = objStates[i].getEntries();
-                if (entries[entryIndex] instanceof VirtualObjectNode) {
-                    ObjectState obj = blockStates.get(i).getObjectState((VirtualObjectNode) entries[entryIndex]);
+                ValueNode entry = objStates[i].getEntry(entryIndex);
+                if (entry instanceof VirtualObjectNode) {
+                    ObjectState obj = blockStates.get(i).getObjectState((VirtualObjectNode) entry);
                     Block predecessor = mergeBlock.getPredecessors().get(i);
                     materialized |= ensureMaterialized(blockStates.get(i), obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_MERGE);
-                    entries[entryIndex] = obj.getMaterializedValue();
+                    if (objStates[i].isVirtual()) {
+                        objStates[i].setEntry(entryIndex, entry = obj.getMaterializedValue());
+                    }
                 }
-                afterMergeEffects.addPhiInput(phi, entries[entryIndex]);
+                afterMergeEffects.addPhiInput(phi, entry);
             }
             return materialized;
         }
@@ -617,7 +610,7 @@
                 if (!state.isVirtual()) {
                     break;
                 }
-                afterMergeEffects.addPhiInput(phi, state.getEntries()[entryIndex]);
+                afterMergeEffects.addPhiInput(phi, state.getEntry(entryIndex));
             }
         }