# HG changeset patch # User Lukas Stadler # Date 1351668042 -3600 # Node ID b01f9c391e17e2ffd8e1567da4c3fd6b6c7d8c54 # Parent 7e371de0de7de790e85ec621a77f260e50caf08a first part of PEA refactoring diff -r 7e371de0de7d -r b01f9c391e17 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java Tue Oct 30 23:59:59 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java Wed Oct 31 08:20:42 2012 +0100 @@ -36,9 +36,9 @@ class BlockState extends MergeableBlockState { - final HashMap objectStates = new HashMap<>(); - final HashMap objectAliases = new HashMap<>(); - final HashMap scalarAliases = new HashMap<>(); + private final HashMap objectStates = new HashMap<>(); + private final HashMap objectAliases = new HashMap<>(); + private final HashMap scalarAliases = new HashMap<>(); public BlockState() { } @@ -84,38 +84,37 @@ private void materializeChangedBefore(FixedNode fixed, VirtualObjectNode virtual, HashSet deferred, GraphEffectList deferredStores, GraphEffectList materializeEffects) { trace("materializing %s at %s", virtual, fixed); ObjectState obj = objectState(virtual); - if (obj.lockCount > 0 && obj.virtual.type().isArrayClass()) { + if (obj.getLockCount() > 0 && obj.virtual.type().isArrayClass()) { throw new BailoutException("array materialized with lock"); } - MaterializeObjectNode materialize = new MaterializeObjectNode(virtual, obj.lockCount > 0); - ValueNode[] values = new ValueNode[obj.fieldState.length]; + MaterializeObjectNode materialize = new MaterializeObjectNode(virtual, obj.getLockCount() > 0); + ValueNode[] values = new ValueNode[obj.getEntries().length]; materialize.setProbability(fixed.probability()); - ValueNode[] fieldState = obj.fieldState; - obj.fieldState = null; - obj.materializedValue = materialize; + ValueNode[] fieldState = obj.getEntries(); + obj.setMaterializedValue(materialize); deferred.add(virtual); for (int i = 0; i < fieldState.length; i++) { ObjectState valueObj = objectState(fieldState[i]); if (valueObj != null) { - if (valueObj.materializedValue == null) { + if (valueObj.getMaterializedValue() == null) { materializeChangedBefore(fixed, valueObj.virtual, deferred, deferredStores, materializeEffects); } if (deferred.contains(valueObj.virtual)) { Kind fieldKind; CyclicMaterializeStoreNode store; if (virtual instanceof VirtualArrayNode) { - store = new CyclicMaterializeStoreNode(materialize, valueObj.materializedValue, i); + store = new CyclicMaterializeStoreNode(materialize, valueObj.getMaterializedValue(), i); fieldKind = ((VirtualArrayNode) virtual).componentType().getKind(); } else { VirtualInstanceNode instanceObject = (VirtualInstanceNode) virtual; - store = new CyclicMaterializeStoreNode(materialize, valueObj.materializedValue, instanceObject.field(i)); + store = new CyclicMaterializeStoreNode(materialize, valueObj.getMaterializedValue(), instanceObject.field(i)); fieldKind = instanceObject.field(i).getType().getKind(); } deferredStores.addFixedNodeBefore(store, fixed); values[i] = ConstantNode.defaultForKind(fieldKind, fixed.graph()); } else { - values[i] = valueObj.materializedValue; + values[i] = valueObj.getMaterializedValue(); } } else { values[i] = fieldState[i]; @@ -161,8 +160,41 @@ return objectStates.values(); } + public Iterable virtualObjects() { + return objectAliases.values(); + } + @Override public String toString() { return objectStates.toString(); } + + public static BlockState meetAliases(List states) { + BlockState newState = new BlockState(); + + newState.objectAliases.putAll(states.get(0).objectAliases); + for (int i = 1; i < states.size(); i++) { + BlockState state = states.get(i); + for (Map.Entry entry : states.get(0).objectAliases.entrySet()) { + if (state.objectAliases.containsKey(entry.getKey())) { + assert state.objectAliases.get(entry.getKey()) == entry.getValue(); + } else { + newState.objectAliases.remove(entry.getKey()); + } + } + } + + newState.scalarAliases.putAll(states.get(0).scalarAliases); + for (int i = 1; i < states.size(); i++) { + BlockState state = states.get(i); + for (Map.Entry entry : states.get(0).scalarAliases.entrySet()) { + if (state.scalarAliases.containsKey(entry.getKey())) { + assert state.scalarAliases.get(entry.getKey()) == entry.getValue(); + } else { + newState.scalarAliases.remove(entry.getKey()); + } + } + } + return newState; + } } diff -r 7e371de0de7d -r b01f9c391e17 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java Tue Oct 30 23:59:59 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java Wed Oct 31 08:20:42 2012 +0100 @@ -28,6 +28,11 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +/** + * An {@link EffectList} can be used to maintain a list of {@link Effect}s and backtrack to a previous state by + * truncating the list. It can also maintain a level for each effect, which helps in creating a string representation + * for the list. + */ public class EffectList implements Iterable { public abstract static class Effect { @@ -178,4 +183,19 @@ public boolean isEmpty() { return size == 0; } + + @Override + public String toString() { + StringBuilder str = new StringBuilder(); + for (int i = 0; i < size(); i++) { + Effect effect = get(i); + if (effect.isVisible()) { + for (int i2 = 0; i2 < levelAt(i); i2++) { + str.append(" "); + } + str.append(effect).toString(); + } + } + return str.toString(); + } } diff -r 7e371de0de7d -r b01f9c391e17 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 Tue Oct 30 23:59:59 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java Wed Oct 31 08:20:42 2012 +0100 @@ -25,16 +25,21 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.virtual.*; +/** + * This class describes the state of a virtual object while iterating over the graph. + * It describes the fields or array elements (called "entries") and the lock count if the object is still virtual. + * If the object was materialized, it contains the current materialized value. + */ class ObjectState { public final VirtualObjectNode virtual; - public ValueNode[] fieldState; - public ValueNode materializedValue; - public int lockCount; + private ValueNode[] entries; + private ValueNode materializedValue; + private int lockCount; - public ObjectState(VirtualObjectNode virtual, ValueNode[] fieldState, int lockCount) { + public ObjectState(VirtualObjectNode virtual, ValueNode[] entries, int lockCount) { this.virtual = virtual; - this.fieldState = fieldState; + this.entries = entries; this.lockCount = lockCount; } @@ -46,7 +51,7 @@ private ObjectState(ObjectState other) { virtual = other.virtual; - fieldState = other.fieldState == null ? null : other.fieldState.clone(); + entries = other.entries == null ? null : other.entries.clone(); materializedValue = other.materializedValue; lockCount = other.lockCount; } @@ -56,15 +61,64 @@ return new ObjectState(this); } + public boolean isVirtual() { + assert (entries == null) ^ (materializedValue == null); + return materializedValue == null; + } + + public ValueNode[] getEntries() { + assert isVirtual(); + return entries; + } + + public ValueNode getEntry(int index) { + assert isVirtual(); + return entries[index]; + } + + public void setEntry(int index, ValueNode value) { + assert isVirtual(); + entries[index] = value; + } + + public ValueNode getMaterializedValue() { + assert !isVirtual(); + return materializedValue; + } + + public void setMaterializedValue(ValueNode value) { + assert isVirtual(); + materializedValue = value; + entries = null; + } + + public void updateMaterializedValue(ValueNode value) { + assert !isVirtual(); + materializedValue = value; + } + + public int getLockCount() { + assert isVirtual(); + return lockCount; + } + + public void incLockCount() { + lockCount++; + } + + public void decLockCount() { + lockCount--; + } + @Override public String toString() { StringBuilder str = new StringBuilder().append('{'); if (lockCount > 0) { str.append('l').append(lockCount).append(' '); } - if (fieldState != null) { - for (int i = 0; i < fieldState.length; i++) { - str.append(virtual.fieldName(i)).append('=').append(fieldState[i]).append(' '); + if (entries != null) { + for (int i = 0; i < entries.length; i++) { + str.append(virtual.fieldName(i)).append('=').append(entries[i]).append(' '); } } if (materializedValue != null) { diff -r 7e371de0de7d -r b01f9c391e17 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java Tue Oct 30 23:59:59 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeAnalysisPhase.java Wed Oct 31 08:20:42 2012 +0100 @@ -36,6 +36,12 @@ public class PartialEscapeAnalysisPhase extends Phase { + private final GraalCodeCacheProvider runtime; + + public PartialEscapeAnalysisPhase(GraalCodeCacheProvider runtime) { + this.runtime = runtime; + } + public static final void trace(String format, Object... obj) { if (GraalOptions.TraceEscapeAnalysis) { Debug.log(format, obj); @@ -46,12 +52,6 @@ System.out.print(String.format(format, obj)); } - private final GraalCodeCacheProvider runtime; - - public PartialEscapeAnalysisPhase(GraalCodeCacheProvider runtime) { - this.runtime = runtime; - } - @Override protected void run(StructuredGraph graph) { SchedulePhase schedule = new SchedulePhase(); @@ -61,20 +61,11 @@ // apply the effects collected during the escape analysis iteration ArrayList obsoleteNodes = new ArrayList<>(); - for (int i = 0; i < closure.effects.size(); i++) { - Effect effect = closure.effects.get(i); + for (Effect effect : closure.effects) { effect.apply(graph, obsoleteNodes); - if (GraalOptions.TraceEscapeAnalysis) { - if (effect.isVisible()) { - int level = closure.effects.levelAt(i); - StringBuilder str = new StringBuilder(); - for (int i2 = 0; i2 < level; i2++) { - str.append(" "); - } - trace(str.append(effect).toString()); - } - } } + trace("%s\n", closure.effects); + Debug.dump(graph, "after PartialEscapeAnalysis"); assert noObsoleteNodes(graph, obsoleteNodes); diff -r 7e371de0de7d -r b01f9c391e17 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 Tue Oct 30 23:59:59 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Wed Oct 31 08:20:42 2012 +0100 @@ -108,10 +108,10 @@ ValueNode value = node instanceof PiNode ? ((PiNode) node).object() : ((ValueProxyNode) node).value(); ObjectState obj = state.objectState(value); if (obj != null) { - if (obj.materializedValue == null) { + if (obj.isVirtual()) { state.addAndMarkAlias(obj.virtual, node, usages); } else { - effects.replaceFirstInput(node, value, obj.materializedValue); + effects.replaceFirstInput(node, value, obj.getMaterializedValue()); } usageFound = true; } @@ -119,7 +119,7 @@ CheckCastNode x = (CheckCastNode) node; ObjectState obj = state.objectState(x.object()); if (obj != null) { - if (obj.materializedValue == null) { + if (obj.isVirtual()) { if (obj.virtual.type().isSubtypeOf(x.type())) { state.addAndMarkAlias(obj.virtual, x, usages); effects.deleteFixedNode(x); @@ -127,7 +127,7 @@ replaceWithMaterialized(x.object(), x, state, obj); } } else { - effects.replaceFirstInput(x, x.object(), obj.materializedValue); + effects.replaceFirstInput(x, x.object(), obj.getMaterializedValue()); } usageFound = true; } @@ -143,16 +143,16 @@ if (obj != null) { Debug.log("monitor operation %s on %s\n", x, obj.virtual); if (node instanceof MonitorEnterNode) { - obj.lockCount++; + obj.incLockCount(); } else { assert node instanceof MonitorExitNode; - obj.lockCount--; + obj.decLockCount(); } - if (obj.materializedValue == null) { + if (obj.isVirtual()) { effects.replaceFirstInput(node, x.object(), obj.virtual); effects.eliminateMonitor(x); } else { - effects.replaceFirstInput(node, x.object(), obj.materializedValue); + effects.replaceFirstInput(node, x.object(), obj.getMaterializedValue()); } usageFound = true; } @@ -161,11 +161,10 @@ ObjectState obj = state.objectState(x.object()); if (obj != null) { if (obj.virtual instanceof VirtualArrayNode) { - obj.fieldState[x.targetIndex()] = x.value(); + obj.setEntry(x.targetIndex(), x.value()); } else { VirtualInstanceNode instance = (VirtualInstanceNode) obj.virtual; - int index = instance.fieldIndex(x.targetField()); - obj.fieldState[index] = x.value(); + obj.setEntry(instance.fieldIndex(x.targetField()), x.value()); } effects.deleteFixedNode(x); usageFound = true; @@ -180,8 +179,8 @@ // the field does not exist in the virtual object ensureMaterialized(state, obj, x); } - if (obj.materializedValue == null) { - ValueNode result = obj.fieldState[fieldIndex]; + if (obj.isVirtual()) { + ValueNode result = obj.getEntry(fieldIndex); ObjectState resultObj = state.objectState(result); if (resultObj != null) { state.addAndMarkAlias(resultObj.virtual, x, usages); @@ -190,7 +189,7 @@ } effects.deleteFixedNode(x); } else { - effects.replaceFirstInput(x, x.object(), obj.materializedValue); + effects.replaceFirstInput(x, x.object(), obj.getMaterializedValue()); } usageFound = true; } @@ -206,11 +205,11 @@ // the field does not exist in the virtual object ensureMaterialized(state, obj, x); } - if (obj.materializedValue == null) { - obj.fieldState[fieldIndex] = state.scalarAlias(value); + if (obj.isVirtual()) { + obj.setEntry(fieldIndex, state.scalarAlias(value)); effects.deleteFixedNode(x); } else { - effects.replaceFirstInput(x, object, obj.materializedValue); + effects.replaceFirstInput(x, object, obj.getMaterializedValue()); ObjectState valueObj = state.objectState(value); if (valueObj != null) { replaceWithMaterialized(value, x, state, valueObj); @@ -229,14 +228,14 @@ ValueNode array = x.array(); ObjectState arrayObj = state.objectState(array); if (arrayObj != null) { - if (arrayObj.materializedValue == null) { + if (arrayObj.isVirtual()) { ValueNode indexValue = state.scalarAlias(x.index()); int index = indexValue.isConstant() ? indexValue.asConstant().asInt() : -1; - if (index < 0 || index >= arrayObj.fieldState.length) { + if (index < 0 || index >= arrayObj.getEntries().length) { // out of bounds or not constant replaceWithMaterialized(array, x, state, arrayObj); } else { - ValueNode result = arrayObj.fieldState[index]; + ValueNode result = arrayObj.getEntry(index); ObjectState resultObj = state.objectState(result); if (resultObj != null) { state.addAndMarkAlias(resultObj.virtual, x, usages); @@ -246,7 +245,7 @@ effects.deleteFixedNode(x); } } else { - effects.replaceFirstInput(x, array, arrayObj.materializedValue); + effects.replaceFirstInput(x, array, arrayObj.getMaterializedValue()); } usageFound = true; } @@ -258,21 +257,21 @@ ObjectState valueObj = state.objectState(value); if (arrayObj != null) { - if (arrayObj.materializedValue == null) { + if (arrayObj.isVirtual()) { ValueNode indexValue = state.scalarAlias(x.index()); int index = indexValue.isConstant() ? indexValue.asConstant().asInt() : -1; - if (index < 0 || index >= arrayObj.fieldState.length) { + if (index < 0 || index >= arrayObj.getEntries().length) { // out of bounds or not constant replaceWithMaterialized(array, x, state, arrayObj); if (valueObj != null) { replaceWithMaterialized(value, x, state, valueObj); } } else { - arrayObj.fieldState[index] = state.scalarAlias(value); + arrayObj.setEntry(index, state.scalarAlias(value)); effects.deleteFixedNode(x); } } else { - effects.replaceFirstInput(x, array, arrayObj.materializedValue); + effects.replaceFirstInput(x, array, arrayObj.getMaterializedValue()); if (valueObj != null) { replaceWithMaterialized(value, x, state, valueObj); } @@ -326,8 +325,8 @@ ObjectEqualsNode x = (ObjectEqualsNode) node; ObjectState xObj = state.objectState(x.x()); ObjectState yObj = state.objectState(x.y()); - boolean xVirtual = xObj != null && xObj.materializedValue == null; - boolean yVirtual = yObj != null && yObj.materializedValue == null; + boolean xVirtual = xObj != null && xObj.isVirtual(); + boolean yVirtual = yObj != null && yObj.isVirtual(); if (xVirtual ^ yVirtual) { // one of them is virtual: they can never be the same objects @@ -340,12 +339,12 @@ } else { if (xObj != null || yObj != null) { if (xObj != null) { - assert xObj.materializedValue != null; - effects.replaceFirstInput(x, x.x(), xObj.materializedValue); + assert !xObj.isVirtual(); + effects.replaceFirstInput(x, x.x(), xObj.getMaterializedValue()); } if (yObj != null) { - assert yObj.materializedValue != null; - effects.replaceFirstInput(x, x.y(), yObj.materializedValue); + assert !yObj.isVirtual(); + effects.replaceFirstInput(x, x.y(), yObj.getMaterializedValue()); } usageFound = true; } @@ -393,7 +392,7 @@ } }); for (ObjectState obj : state.states()) { - if (obj.materializedValue == null && obj.lockCount > 0) { + if (obj.isVirtual() && obj.getLockCount() > 0) { virtual.add(obj); } } @@ -401,11 +400,11 @@ ArrayDeque queue = new ArrayDeque<>(virtual); while (!queue.isEmpty()) { ObjectState obj = queue.removeLast(); - if (obj.materializedValue == null) { - for (ValueNode field : obj.fieldState) { + if (obj.isVirtual()) { + for (ValueNode field : obj.getEntries()) { ObjectState fieldObj = state.objectState(field); if (fieldObj != null) { - if (fieldObj.materializedValue == null && !virtual.contains(fieldObj)) { + if (fieldObj.isVirtual() && !virtual.contains(fieldObj)) { virtual.add(fieldObj); queue.addLast(fieldObj); } @@ -415,21 +414,21 @@ } for (ObjectState obj : virtual) { EscapeObjectState v; - if (obj.materializedValue == null) { - ValueNode[] fieldState = obj.fieldState.clone(); + if (obj.isVirtual()) { + ValueNode[] fieldState = obj.getEntries().clone(); for (int i = 0; i < fieldState.length; i++) { ObjectState valueObj = state.objectState(fieldState[i]); if (valueObj != null) { - if (valueObj.materializedValue == null) { + if (valueObj.isVirtual()) { fieldState[i] = valueObj.virtual; } else { - fieldState[i] = valueObj.materializedValue; + fieldState[i] = valueObj.getMaterializedValue(); } } } v = new VirtualObjectState(obj.virtual, fieldState); } else { - v = new MaterializedObjectState(obj.virtual, obj.materializedValue); + v = new MaterializedObjectState(obj.virtual, obj.getMaterializedValue()); } effects.addVirtualMapping(stateAfter, v, reusedVirtualObjects); } @@ -455,49 +454,26 @@ private void ensureMaterialized(BlockState state, ObjectState obj, FixedNode materializeBefore) { assert obj != null; - if (obj.materializedValue == null) { + if (obj.isVirtual()) { state.materializeBefore(materializeBefore, obj.virtual, effects); } - assert obj.materializedValue != null; + assert !obj.isVirtual(); } private void replaceWithMaterialized(ValueNode value, FixedNode usage, BlockState state, ObjectState obj) { ensureMaterialized(state, obj, usage); - effects.replaceFirstInput(usage, value, obj.materializedValue); + effects.replaceFirstInput(usage, value, obj.getMaterializedValue()); } private void replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, BlockState state, ObjectState obj) { ensureMaterialized(state, obj, materializeBefore); - effects.replaceFirstInput(usage, value, obj.materializedValue); + effects.replaceFirstInput(usage, value, obj.getMaterializedValue()); } @Override protected BlockState merge(MergeNode merge, List states) { - BlockState newState = new BlockState(); - newState.objectAliases.putAll(states.get(0).objectAliases); - for (int i = 1; i < states.size(); i++) { - BlockState state = states.get(i); - for (Map.Entry entry : states.get(0).objectAliases.entrySet()) { - if (state.objectAliases.containsKey(entry.getKey())) { - assert state.objectAliases.get(entry.getKey()) == entry.getValue(); - } else { - newState.objectAliases.remove(entry.getKey()); - } - } - } - - newState.scalarAliases.putAll(states.get(0).scalarAliases); - for (int i = 1; i < states.size(); i++) { - BlockState state = states.get(i); - for (Map.Entry entry : states.get(0).scalarAliases.entrySet()) { - if (state.scalarAliases.containsKey(entry.getKey())) { - assert state.scalarAliases.get(entry.getKey()) == entry.getValue(); - } else { - newState.scalarAliases.remove(entry.getKey()); - } - } - } + BlockState newState = BlockState.meetAliases(states); // Iterative processing: // Merging the materialized/virtual state of virtual objects can lead to new materializations, which can @@ -507,23 +483,23 @@ do { materialized = false; // use a hash set to make the values distinct... - for (VirtualObjectNode object : new HashSet<>(newState.objectAliases.values())) { - ObjectState resultState = newState.objectStates.get(object); - if (resultState == null || resultState.materializedValue == null) { + for (VirtualObjectNode object : newState.virtualObjects()) { + ObjectState resultState = newState.objectStateOptional(object); + if (resultState == null || resultState.isVirtual()) { int virtual = 0; - int lockCount = states.get(0).objectState(object).lockCount; - ValueNode singleValue = states.get(0).objectState(object).materializedValue; + int lockCount = states.get(0).objectState(object).getLockCount(); + ValueNode singleValue = states.get(0).objectState(object).getMaterializedValue(); for (BlockState state : states) { ObjectState obj = state.objectState(object); - if (obj.materializedValue == null) { + if (obj.isVirtual()) { virtual++; singleValue = null; } else { - if (obj.materializedValue != singleValue) { + if (obj.getMaterializedValue() != singleValue) { singleValue = null; } } - assert obj.lockCount == lockCount : "mismatching lock counts"; + assert obj.getLockCount() == lockCount : "mismatching lock counts"; } if (virtual < states.size()) { @@ -533,9 +509,9 @@ for (int i = 0; i < states.size(); i++) { BlockState state = states.get(i); ObjectState obj = state.objectState(object); - materialized |= obj.materializedValue == null; + materialized |= obj.isVirtual(); ensureMaterialized(state, obj, merge.forwardEndAt(i)); - effects.addPhiInput(materializedValuePhi, obj.materializedValue); + effects.addPhiInput(materializedValuePhi, obj.getMaterializedValue()); } newState.addObject(object, new ObjectState(object, materializedValuePhi, lockCount)); } else { @@ -543,12 +519,12 @@ } } else { assert virtual == states.size(); - ValueNode[] values = states.get(0).objectState(object).fieldState.clone(); + ValueNode[] values = states.get(0).objectState(object).getEntries().clone(); PhiNode[] phis = new PhiNode[values.length]; int mismatch = 0; for (int i = 1; i < states.size(); i++) { BlockState state = states.get(i); - ValueNode[] fields = state.objectState(object).fieldState; + ValueNode[] fields = state.objectState(object).getEntries(); for (int index = 0; index < values.length; index++) { if (phis[index] == null && values[index] != fields[index]) { mismatch++; @@ -560,14 +536,14 @@ if (mismatch > 0) { for (int i = 0; i < states.size(); i++) { BlockState state = states.get(i); - ValueNode[] fields = state.objectState(object).fieldState; + ValueNode[] fields = state.objectState(object).getEntries(); for (int index = 0; index < values.length; index++) { if (phis[index] != null) { ObjectState obj = state.objectState(fields[index]); if (obj != null) { - materialized |= obj.materializedValue == null; + materialized |= obj.isVirtual(); ensureMaterialized(state, obj, merge.forwardEndAt(i)); - fields[index] = obj.materializedValue; + fields[index] = obj.getMaterializedValue(); } effects.addPhiInput(phis[index], fields[index]); } @@ -605,7 +581,7 @@ ValueNode value = phi.valueAt(i); ObjectState obj = states.get(i).objectState(value); if (obj != null) { - if (obj.materializedValue == null) { + if (obj.isVirtual()) { virtualInputs++; if (i == 0) { sameObject = obj.virtual; @@ -623,7 +599,7 @@ } } } else { - effects.setPhiInput(phi, obj.materializedValue, i); + effects.setPhiInput(phi, obj.getMaterializedValue(), i); } } } @@ -648,7 +624,7 @@ ValueNode value = phi.valueAt(i); ObjectState obj = states.get(i).objectState(value); if (obj != null) { - materialized |= obj.materializedValue == null; + materialized |= obj.isVirtual(); replaceWithMaterialized(value, phi, merge.forwardEndAt(i), states.get(i), obj); } } @@ -671,18 +647,18 @@ for (PhiDesc desc : phis) { ObjectState obj = state.objectState(desc.virtualObject); - if (obj.materializedValue == null) { - ValueNode value = obj.fieldState[desc.fieldIndex]; + if (obj.isVirtual()) { + ValueNode value = obj.getEntry(desc.fieldIndex); ObjectState valueObj = state.objectState(value); if (valueObj != null) { - assert valueObj.materializedValue != null; - value = valueObj.materializedValue; + assert !valueObj.isVirtual(); + value = valueObj.getMaterializedValue(); } PhiNode phiNode = new PhiNode(value.kind(), loop.loopBegin()); effects.addFloatingNode(phiNode); effects.addPhiInput(phiNode, value); - obj.fieldState[desc.fieldIndex] = phiNode; + obj.setEntry(desc.fieldIndex, phiNode); } } @@ -690,10 +666,10 @@ if (usages.isMarked(phi) && phi.type() == PhiType.Value) { ObjectState initialObj = initialState.objectState(phi.valueAt(0)); if (initialObj != null) { - if (initialObj.materializedValue == null) { + if (initialObj.isVirtual()) { state.addAndMarkAlias(initialObj.virtual, phi, usages); } else { - successEffects.setPhiInput(phi, initialObj.materializedValue, 0); + successEffects.setPhiInput(phi, initialObj.getMaterializedValue(), 0); } } } @@ -727,7 +703,7 @@ effects.decLevel(); for (VirtualObjectNode virtualObject : additionalMaterializations) { ObjectState obj = initialState.objectState(virtualObject); - if (obj.materializedValue == null) { + if (obj.isVirtual()) { initialState.materializeBefore(loop.loopBegin().forwardEnd(), virtualObject, effects); } } @@ -748,33 +724,32 @@ } for (ObjectState obj : exitState.states()) { ObjectState initialObj = initialState.objectStateOptional(obj.virtual); - if (obj.materializedValue == null) { - for (int i = 0; i < obj.fieldState.length; i++) { - ValueNode value = obj.fieldState[i]; + if (obj.isVirtual()) { + for (int i = 0; i < obj.getEntries().length; i++) { + ValueNode value = obj.getEntry(i); ObjectState valueObj = exitState.objectState(value); if (valueObj == null) { - if ((value instanceof PhiNode && ((PhiNode) value).merge() == exitNode.loopBegin()) || initialObj == null || initialObj.materializedValue != null || - initialObj.fieldState[i] != value) { + if ((value instanceof PhiNode && ((PhiNode) value).merge() == exitNode.loopBegin()) || initialObj == null || !initialObj.isVirtual() || initialObj.getEntry(i) != value) { ValueProxyNode proxy = new ValueProxyNode(value, exitNode, PhiType.Value); - obj.fieldState[i] = proxy; + obj.setEntry(i, proxy); effects.addFloatingNode(proxy); } } } } else { - if (initialObj == null || initialObj.materializedValue == null) { + if (initialObj == null || initialObj.isVirtual()) { ValueProxyNode proxy = proxies.get(obj.virtual); if (proxy == null) { - proxy = new ValueProxyNode(obj.materializedValue, exitNode, PhiType.Value); + proxy = new ValueProxyNode(obj.getMaterializedValue(), exitNode, PhiType.Value); effects.addFloatingNode(proxy); } else { - effects.replaceFirstInput(proxy, proxy.value(), obj.materializedValue); + effects.replaceFirstInput(proxy, proxy.value(), obj.getMaterializedValue()); // nothing to do - will be handled in processNode } - obj.materializedValue = proxy; + obj.updateMaterializedValue(proxy); } else { - assert initialObj.materializedValue == obj.materializedValue : "materialized value is not allowed to change within loops: " + initialObj.materializedValue + " vs. " + - obj.materializedValue; + assert initialObj.getMaterializedValue() == obj.getMaterializedValue() : "materialized value is not allowed to change within loops: " + initialObj.getMaterializedValue() + + " vs. " + obj.getMaterializedValue(); } } } @@ -819,18 +794,18 @@ materialized = false; for (ObjectState state : initialState.states()) { ObjectState endState = loopEndState.objectState(state.virtual); - if (state.materializedValue == null) { - if (endState.materializedValue == null) { - assert state.fieldState.length == endState.fieldState.length; - for (int i = 0; endState.fieldState != null && i < state.fieldState.length; i++) { - ValueNode value = state.fieldState[i]; - ValueNode endValue = endState.fieldState[i]; + if (state.isVirtual()) { + if (endState.isVirtual()) { + assert state.getEntries().length == endState.getEntries().length; + for (int i = 0; endState.isVirtual() && i < state.getEntries().length; i++) { + ValueNode value = state.getEntry(i); + ValueNode endValue = endState.getEntry(i); ObjectState valueObj = initialState.objectState(value); ObjectState endValueObj = loopEndState.objectState(endValue); if (valueObj != null) { - if (valueObj.materializedValue == null) { - if (endValueObj == null || endValueObj.materializedValue != null || valueObj.virtual != endValueObj.virtual) { + if (valueObj.isVirtual()) { + if (endValueObj == null || !endValueObj.isVirtual() || valueObj.virtual != endValueObj.virtual) { additionalMaterializations.add(valueObj.virtual); } else { // endValue is also virtual and refers to the same virtual object, so we're @@ -840,7 +815,7 @@ } else { if (value instanceof PhiNode && ((PhiNode) value).merge() == loopBegin) { if (endValueObj != null) { - if (endValueObj.materializedValue == null) { + if (endValueObj.isVirtual()) { loopEndState.materializeBefore(loopEnd, endValueObj.virtual, successEffects); materialized = true; } @@ -856,12 +831,12 @@ for (PhiNode phi : loopBegin.phis().snapshot()) { if (usages.isMarked(phi) && phi.type() == PhiType.Value) { ObjectState initialObj = initialState.objectState(phi.valueAt(0)); - boolean initialMaterialized = initialObj == null || initialObj.materializedValue != null; + boolean initialMaterialized = initialObj == null || !initialObj.isVirtual(); ObjectState loopEndObj = loopEndState.objectState(phi.valueAt(loopEnd)); - if (loopEndObj == null || loopEndObj.materializedValue != null) { + if (loopEndObj == null || !loopEndObj.isVirtual()) { if (loopEndObj != null) { - successEffects.setPhiInput(phi, loopEndObj.materializedValue, loopBegin.phiPredecessorIndex(loopEnd)); + successEffects.setPhiInput(phi, loopEndObj.getMaterializedValue(), loopBegin.phiPredecessorIndex(loopEnd)); } if (!initialMaterialized) { additionalMaterializations.add(initialObj.virtual); @@ -882,25 +857,25 @@ for (ObjectState state : initialState.states()) { ObjectState endState = loopEndState.objectState(state.virtual); - if (state.materializedValue == null) { - if (endState.materializedValue == null) { - assert state.fieldState.length == endState.fieldState.length; - for (int i = 0; i < state.fieldState.length; i++) { - ValueNode value = state.fieldState[i]; - ValueNode endValue = endState.fieldState[i]; + if (state.isVirtual()) { + if (endState.isVirtual()) { + assert state.getEntries().length == endState.getEntries().length; + for (int i = 0; i < state.getEntries().length; i++) { + ValueNode value = state.getEntry(i); + ValueNode endValue = endState.getEntry(i); ObjectState valueObj = initialState.objectState(value); ObjectState endValueObj = loopEndState.objectState(endValue); if (valueObj != null) { - if (valueObj.materializedValue == null) { - if (endValueObj == null || endValueObj.materializedValue != null || valueObj.virtual != endValueObj.virtual) { + if (valueObj.isVirtual()) { + if (endValueObj == null || !endValueObj.isVirtual() || valueObj.virtual != endValueObj.virtual) { assert !additionalMaterializations.isEmpty(); } else { // endValue is also virtual and refers to the same virtual object, so we're // good. } } else { - if ((endValueObj != null && endValueObj.materializedValue != valueObj.materializedValue) || (endValueObj == null && valueObj.materializedValue != endValue)) { + if ((endValueObj != null && endValueObj.getMaterializedValue() != valueObj.getMaterializedValue()) || (endValueObj == null && valueObj.getMaterializedValue() != endValue)) { phis.add(new PhiDesc(state.virtual, i)); } else { // either endValue has the same materialized value as value or endValue is the @@ -910,10 +885,10 @@ } else { if (value instanceof PhiNode && ((PhiNode) value).merge() == loopBegin) { if (endValueObj != null) { - if (endValueObj.materializedValue == null) { + if (endValueObj.isVirtual()) { assert !additionalMaterializations.isEmpty(); } - successEffects.addPhiInput((PhiNode) value, endValueObj.materializedValue); + successEffects.addPhiInput((PhiNode) value, endValueObj.getMaterializedValue()); } else { successEffects.addPhiInput((PhiNode) value, endValue); } @@ -928,10 +903,10 @@ } } else { // state.materializedValue != null - if (endState.materializedValue == null) { + if (endState.isVirtual()) { // throw new GraalInternalError("un-materialized object state at %s", loopEnd); } else { - if (state.materializedValue != endState.materializedValue) { + if (state.getMaterializedValue() != endState.getMaterializedValue()) { // throw new GraalInternalError("changed materialized value during loop: %s vs %s", // state.materializedValue, endState.materializedValue); }