# HG changeset patch # User Lukas Stadler # Date 1423845778 -3600 # Node ID afe80ca4b0f02a213d67d2f037089f05b33c2db3 # Parent 5ea169a3bf81ef9e714f8df187d6b2b10f4561cb cache EscapeObjectStates during PEA diff -r 5ea169a3bf81 -r afe80ca4b0f0 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java --- 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 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 diff -r 5ea169a3bf81 -r afe80ca4b0f0 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java --- 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 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 diff -r 5ea169a3bf81 -r afe80ca4b0f0 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java --- 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> extends EffectsClosure { @@ -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 virtual) { + private static void addVirtualMappings(GraphEffectList effects, FrameState frameState, Set 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 virtual) { + private void collectLockedVirtualObjects(final BlockT state, Set 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)); } }