# HG changeset patch # User Lukas Stadler # Date 1380712705 -7200 # Node ID 3aef4d88fbb946b48303783c9f0dac2ef502159f # Parent 7a5182bd21755604d02b2ca5dc2b8518db12d2a3 simplify PEA block states by turning scalarAliases and objectAliases into one global NodeMap diff -r 7a5182bd2175 -r 3aef4d88fbb9 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsBlockState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsBlockState.java Wed Oct 02 10:19:43 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsBlockState.java Wed Oct 02 13:18:25 2013 +0200 @@ -24,48 +24,14 @@ import java.util.*; -import com.oracle.graal.nodes.*; - public abstract class EffectsBlockState> { - protected final IdentityHashMap scalarAliases; - - protected EffectsBlockState() { - scalarAliases = new IdentityHashMap<>(); - } - - protected EffectsBlockState(EffectsBlockState other) { - scalarAliases = new IdentityHashMap<>(other.scalarAliases); - } - - public void addScalarAlias(ValueNode alias, ValueNode value) { - scalarAliases.put(alias, value); - } - - public ValueNode getScalarAlias(ValueNode alias) { - ValueNode result = scalarAliases.get(alias); - return result == null ? alias : result; - } - @Override public String toString() { - return "Scalar Aliases: " + scalarAliases.toString(); + return ""; } - public void meetAliases(List states) { - scalarAliases.putAll(states.get(0).scalarAliases); - for (int i = 1; i < states.size(); i++) { - EffectsBlockState state = states.get(i); - meetMaps(scalarAliases, state.scalarAliases); - } - } - - public boolean equivalentTo(T other) { - if (this == other) { - return true; - } - return scalarAliases.equals(other.scalarAliases); - } + protected abstract boolean equivalentTo(T other); protected static boolean compareMaps(Map left, Map right) { if (left.size() != right.size()) { diff -r 7a5182bd2175 -r 3aef4d88fbb9 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Wed Oct 02 10:19:43 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Wed Oct 02 13:18:25 2013 +0200 @@ -30,6 +30,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.graph.*; import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo; @@ -40,6 +41,7 @@ private final SchedulePhase schedule; + protected final NodeMap aliases; protected final BlockMap blockEffects; private final IdentityHashMap loopMergeEffects = new IdentityHashMap<>(); @@ -47,6 +49,7 @@ public EffectsClosure(SchedulePhase schedule) { this.schedule = schedule; + this.aliases = schedule.getCFG().graph.createNodeMap(); this.blockEffects = new BlockMap<>(schedule.getCFG()); for (Block block : schedule.getCFG().getBlocks()) { blockEffects.put(block, new GraphEffectList()); @@ -118,6 +121,7 @@ GraphEffectList effects = blockEffects.get(block); FixedWithNextNode lastFixedNode = null; for (Node node : schedule.getBlockToNodesMap().get(block)) { + aliases.set(node, null); changed |= processNode(node, state, effects, lastFixedNode); if (node instanceof FixedWithNextNode) { lastFixedNode = (FixedWithNextNode) node; @@ -202,9 +206,11 @@ this.afterMergeEffects = new GraphEffectList(); } + /** + * @param states the states that should be merged. + */ protected void merge(List states) { newState = getInitialState(); - newState.meetAliases(states); mergeEffects.clear(); afterMergeEffects.clear(); } @@ -213,4 +219,18 @@ protected void commitEnds(List states) { } } + + public void addScalarAlias(ValueNode node, ValueNode alias) { + assert !(alias instanceof VirtualObjectNode); + aliases.set(node, alias); + } + + public ValueNode getScalarAlias(ValueNode node) { + assert !(node instanceof VirtualObjectNode); + if (node == null || !node.isAlive() || aliases.isNew(node)) { + return node; + } + ValueNode result = aliases.get(node); + return (result == null || result instanceof VirtualObjectNode) ? node : result; + } } diff -r 7a5182bd2175 -r 3aef4d88fbb9 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationBlockState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationBlockState.java Wed Oct 02 10:19:43 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationBlockState.java Wed Oct 02 13:18:25 2013 +0200 @@ -92,9 +92,9 @@ return super.equivalentTo(other); } - public void addReadCache(ValueNode object, ResolvedJavaField identity, ValueNode value) { + public void addReadCache(ValueNode object, ResolvedJavaField identity, ValueNode value, PartialEscapeClosure closure) { ValueNode cacheObject; - ObjectState obj = getObjectState(object); + ObjectState obj = closure.getObjectState(this, object); if (obj != null) { assert !obj.isVirtual(); cacheObject = obj.getMaterializedValue(); @@ -104,9 +104,9 @@ readCache.put(new ReadCacheEntry(identity, cacheObject), value); } - public ValueNode getReadCache(ValueNode object, ResolvedJavaField identity) { + public ValueNode getReadCache(ValueNode object, ResolvedJavaField identity, PartialEscapeClosure closure) { ValueNode cacheObject; - ObjectState obj = getObjectState(object); + ObjectState obj = closure.getObjectState(this, object); if (obj != null) { assert !obj.isVirtual(); cacheObject = obj.getMaterializedValue(); @@ -114,13 +114,13 @@ cacheObject = object; } ValueNode cacheValue = readCache.get(new ReadCacheEntry(identity, cacheObject)); - obj = getObjectState(cacheValue); + obj = closure.getObjectState(this, cacheValue); if (obj != null) { assert !obj.isVirtual(); cacheValue = obj.getMaterializedValue(); } else { // assert !scalarAliases.containsKey(cacheValue); - cacheValue = getScalarAlias(cacheValue); + cacheValue = closure.getScalarAlias(cacheValue); } return cacheValue; } diff -r 7a5182bd2175 -r 3aef4d88fbb9 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Wed Oct 02 10:19:43 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Wed Oct 02 13:18:25 2013 +0200 @@ -57,13 +57,13 @@ LoadFieldNode load = (LoadFieldNode) node; if (!load.isVolatile()) { ValueNode object = GraphUtil.unproxify(load.object()); - ValueNode cachedValue = state.getReadCache(object, load.field()); + ValueNode cachedValue = state.getReadCache(object, load.field(), this); if (cachedValue != null) { effects.replaceAtUsages(load, cachedValue); - state.addScalarAlias(load, cachedValue); + addScalarAlias(load, cachedValue); deleted = true; } else { - state.addReadCache(object, load.field(), load); + state.addReadCache(object, load.field(), load, this); } } else { processIdentity(state, ANY_LOCATION); @@ -72,15 +72,15 @@ StoreFieldNode store = (StoreFieldNode) node; if (!store.isVolatile()) { ValueNode object = GraphUtil.unproxify(store.object()); - ValueNode cachedValue = state.getReadCache(object, store.field()); + ValueNode cachedValue = state.getReadCache(object, store.field(), this); - ValueNode value = state.getScalarAlias(store.value()); + ValueNode value = getScalarAlias(store.value()); if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { effects.deleteFixedNode(store); deleted = true; } state.killReadCache(store.field()); - state.addReadCache(object, store.field(), value); + state.addReadCache(object, store.field(), value, this); } else { processIdentity(state, ANY_LOCATION); } @@ -112,7 +112,7 @@ for (Map.Entry entry : exitState.getReadCache().entrySet()) { if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) { - ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity); + ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity, this); if (!(value instanceof ProxyNode) || ((ProxyNode) value).proxyPoint() != exitNode) { ProxyNode proxy = new ProxyNode(value, exitNode, PhiType.Value, null); effects.addFloatingNode(proxy, "readCacheProxy"); @@ -165,7 +165,7 @@ PhiNode phiNode = getCachedPhi(entry, value.kind()); mergeEffects.addFloatingNode(phiNode, "mergeReadCache"); for (int i = 0; i < states.size(); i++) { - afterMergeEffects.addPhiInput(phiNode, states.get(i).getReadCache(key.object, key.identity)); + afterMergeEffects.addPhiInput(phiNode, states.get(i).getReadCache(key.object, key.identity, PEReadEliminationClosure.this)); } newState.readCache.put(key, phiNode); } else if (value != null) { @@ -187,7 +187,7 @@ private void mergeReadCachePhi(PhiNode phi, ResolvedJavaField identity, List states) { ValueNode[] values = new ValueNode[phi.valueCount()]; for (int i = 0; i < phi.valueCount(); i++) { - ValueNode value = states.get(i).getReadCache(phi.valueAt(i), identity); + ValueNode value = states.get(i).getReadCache(phi.valueAt(i), identity, PEReadEliminationClosure.this); if (value == null) { return; } diff -r 7a5182bd2175 -r 3aef4d88fbb9 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java Wed Oct 02 10:19:43 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java Wed Oct 02 13:18:25 2013 +0200 @@ -24,7 +24,6 @@ import java.util.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; import com.oracle.graal.nodes.virtual.*; @@ -32,7 +31,6 @@ public abstract class PartialEscapeBlockState> extends EffectsBlockState { protected final IdentityHashMap objectStates = new IdentityHashMap<>(); - protected final IdentityHashMap objectAliases; /** * Final subclass of PartialEscapeBlockState, for performance and to make everything behave @@ -49,15 +47,12 @@ } protected PartialEscapeBlockState() { - objectAliases = new IdentityHashMap<>(); } protected PartialEscapeBlockState(PartialEscapeBlockState other) { - super(other); for (Map.Entry entry : other.objectStates.entrySet()) { objectStates.put(entry.getKey(), entry.getValue().cloneState()); } - objectAliases = new IdentityHashMap<>(other.objectAliases); } public ObjectState getObjectState(VirtualObjectNode object) { @@ -69,11 +64,6 @@ return objectStates.get(object); } - public ObjectState getObjectState(ValueNode value) { - VirtualObjectNode object = objectAliases.get(value); - return object == null ? null : getObjectState(object); - } - public void materializeBefore(FixedNode fixed, VirtualObjectNode virtual, EscapeState state, GraphEffectList materializeEffects) { PartialEscapeClosure.METRIC_MATERIALIZATIONS.increment(); List objects = new ArrayList<>(2); @@ -100,8 +90,8 @@ values.add(null); } for (int i = 0; i < entries.length; i++) { - ObjectState entryObj = getObjectState(entries[i]); - if (entryObj != null) { + if (entries[i] instanceof VirtualObjectNode) { + ObjectState entryObj = getObjectState((VirtualObjectNode) entries[i]); if (entryObj.isVirtual()) { materializeWithCommit(fixed, entryObj.getVirtualObject(), objects, locks, values, otherAllocations, state); } @@ -122,26 +112,6 @@ VirtualUtil.trace("materialized %s as %s with values %s", virtual, representation, values); } - void addAndMarkAlias(VirtualObjectNode virtual, ValueNode node, NodeBitMap usages) { - objectAliases.put(node, virtual); - if (node.isAlive()) { - for (Node usage : node.usages()) { - markVirtualUsages(usage, usages); - } - } - } - - private void markVirtualUsages(Node node, NodeBitMap usages) { - if (!usages.isNew(node)) { - usages.mark(node); - } - if (node instanceof VirtualState) { - for (Node usage : node.usages()) { - markVirtualUsages(usage, usages); - } - } - } - public void addObject(VirtualObjectNode virtual, ObjectState state) { objectStates.put(virtual, state); } @@ -150,30 +120,18 @@ return objectStates.values(); } - public Collection getVirtualObjects() { - return objectAliases.values(); + public Set getVirtualObjects() { + return objectStates.keySet(); } @Override public String toString() { - return super.toString() + ", Object Aliases: " + objectAliases + ", Object States: " + objectStates; - } - - @Override - public void meetAliases(List states) { - super.meetAliases(states); - objectAliases.putAll(states.get(0).objectAliases); - for (int i = 1; i < states.size(); i++) { - meetMaps(objectAliases, states.get(i).objectAliases); - } + return super.toString() + ", Object States: " + objectStates; } @Override public boolean equivalentTo(T other) { - if (!compareMaps(objectAliases, other.objectAliases) || !compareMaps(objectStates, other.objectStates)) { - return false; - } - return super.equivalentTo(other); + return compareMaps(objectStates, other.objectStates); } protected static boolean compareMaps(Map left, Map right) { diff -r 7a5182bd2175 -r 3aef4d88fbb9 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 Wed Oct 02 10:19:43 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Wed Oct 02 13:18:25 2013 +0200 @@ -79,7 +79,7 @@ public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) { super(schedule); this.usages = schedule.getCFG().graph.createNodeBitMap(); - this.tool = new VirtualizerToolImpl(usages, metaAccess, assumptions); + this.tool = new VirtualizerToolImpl(metaAccess, assumptions, this); } public Map getHints() { @@ -129,7 +129,7 @@ @Override public void apply(Node usage, ValueNode value) { - ObjectState valueObj = state.getObjectState(value); + ObjectState valueObj = getObjectState(state, value); if (valueObj != null) { virtual.add(valueObj); effects.replaceFirstInput(usage, value, valueObj.virtual); @@ -158,8 +158,8 @@ ObjectState obj = queue.removeLast(); if (obj.isVirtual()) { for (ValueNode field : obj.getEntries()) { - ObjectState fieldObj = state.getObjectState(field); - if (fieldObj != null) { + if (field instanceof VirtualObjectNode) { + ObjectState fieldObj = state.getObjectState((VirtualObjectNode) field); if (fieldObj.isVirtual() && !virtual.contains(fieldObj)) { virtual.add(fieldObj); queue.addLast(fieldObj); @@ -173,7 +173,7 @@ if (obj.isVirtual()) { ValueNode[] fieldState = obj.getEntries().clone(); for (int i = 0; i < fieldState.length; i++) { - ObjectState valueObj = state.getObjectState(fieldState[i]); + ObjectState valueObj = getObjectState(state, fieldState[i]); if (valueObj != null) { if (valueObj.isVirtual()) { fieldState[i] = valueObj.virtual; @@ -191,7 +191,7 @@ } } for (ValueNode input : node.inputs().filter(ValueNode.class)) { - ObjectState obj = state.getObjectState(input); + ObjectState obj = getObjectState(state, input); if (obj != null) { if (obj.isVirtual() && node instanceof MethodCallTargetNode) { Invoke invoke = ((MethodCallTargetNode) node).invoke(); @@ -205,7 +205,7 @@ return false; } - private static void ensureMaterialized(PartialEscapeBlockState state, ObjectState obj, FixedNode materializeBefore, GraphEffectList effects, DebugMetric metric) { + private void ensureMaterialized(BlockT state, ObjectState obj, FixedNode materializeBefore, GraphEffectList effects, DebugMetric metric) { assert obj != null; if (obj.getState() == EscapeState.Virtual) { metric.increment(); @@ -216,7 +216,7 @@ assert !obj.isVirtual(); } - private static void replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, PartialEscapeBlockState state, ObjectState obj, GraphEffectList effects, DebugMetric metric) { + private void replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, BlockT state, ObjectState obj, GraphEffectList effects, DebugMetric metric) { ensureMaterialized(state, obj, materializeBefore, effects, metric); effects.replaceFirstInput(usage, value, obj.getMaterializedValue()); } @@ -226,7 +226,7 @@ HashMap proxies = new HashMap<>(); for (ProxyNode proxy : exitNode.proxies()) { - ObjectState obj = exitState.getObjectState(proxy.value()); + ObjectState obj = getObjectState(exitState, proxy.value()); if (obj != null) { proxies.put(obj.virtual, proxy); } @@ -236,8 +236,7 @@ if (obj.isVirtual()) { for (int i = 0; i < obj.getEntries().length; i++) { ValueNode value = obj.getEntry(i); - ObjectState valueObj = exitState.getObjectState(value); - if (valueObj == null) { + if (!(value instanceof VirtualObjectNode)) { if (exitNode.loopBegin().isPhiAtMerge(value) || initialObj == null || !initialObj.isVirtual() || initialObj.getEntry(i) != value) { ProxyNode proxy = new ProxyNode(value, exitNode, PhiType.Value, null); obj.setEntry(i, proxy); @@ -327,16 +326,21 @@ * and so on. */ - HashSet virtualObjects = new HashSet<>(newState.getVirtualObjects()); + HashSet virtualObjTemp = new HashSet<>(states.get(0).getVirtualObjects()); + for (int i = 1; i < states.size(); i++) { + virtualObjTemp.retainAll(states.get(i).getVirtualObjects()); + } + boolean materialized; do { mergeEffects.clear(); afterMergeEffects.clear(); materialized = false; - for (VirtualObjectNode object : virtualObjects) { + for (VirtualObjectNode object : virtualObjTemp) { ObjectState[] objStates = new ObjectState[states.size()]; for (int i = 0; i < states.size(); i++) { - objStates[i] = states.get(i).getObjectState(object); + objStates[i] = states.get(i).getObjectStateOptional(object); + assert objStates[i] != null; } int virtual = 0; ObjectState startObj = objStates[0]; @@ -359,7 +363,7 @@ PhiNode materializedValuePhi = getCachedPhi(object, Kind.Object); mergeEffects.addFloatingNode(materializedValuePhi, "materializedPhi"); for (int i = 0; i < states.size(); i++) { - PartialEscapeBlockState state = states.get(i); + BlockT state = states.get(i); ObjectState obj = objStates[i]; materialized |= obj.isVirtual(); Block predecessor = mergeBlock.getPredecessors().get(i); @@ -396,8 +400,8 @@ break outer; } ValueNode[] fields = objStates[i].getEntries(); - ObjectState obj = states.get(i).getObjectState(fields[index]); - if (obj != null) { + if (fields[index] instanceof VirtualObjectNode) { + ObjectState obj = states.get(i).getObjectState((VirtualObjectNode) fields[index]); materialized |= obj.isVirtual(); Block predecessor = mergeBlock.getPredecessors().get(i); ensureMaterialized(states.get(i), obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_MERGE); @@ -421,6 +425,7 @@ } private boolean processPhi(PhiNode phi, List states) { + aliases.set(phi, null); assert states.size() == phi.valueCount(); int virtualInputs = 0; boolean materialized = false; @@ -430,7 +435,7 @@ boolean hasIdentity = false; for (int i = 0; i < phi.valueCount(); i++) { ValueNode value = phi.valueAt(i); - ObjectState obj = states.get(i).getObjectState(value); + ObjectState obj = getObjectState(states.get(i), value); if (obj != null) { if (obj.isVirtual()) { virtualInputs++; @@ -460,10 +465,10 @@ // nothing to do... } else if (virtualInputs == phi.valueCount()) { if (sameObject != null) { - newState.addAndMarkAlias(sameObject, phi, usages); + addAndMarkAlias(sameObject, phi); } else if (sameType != null && sameEntryCount != -1) { if (!hasIdentity) { - VirtualObjectNode virtual = getValueObjectVirtual(phi, states.get(0).getObjectState(phi.valueAt(0)).virtual); + VirtualObjectNode virtual = getValueObjectVirtual(phi, getObjectState(states.get(0), phi.valueAt(0)).virtual); PhiNode[] phis = getValueObjectMergePhis(phi, virtual.entryCount()); for (int i = 0; i < virtual.entryCount(); i++) { @@ -473,13 +478,13 @@ } mergeEffects.addFloatingNode(phis[i], "valueObjectPhi"); for (int i2 = 0; i2 < phi.valueCount(); i2++) { - afterMergeEffects.addPhiInput(phis[i], states.get(i2).getObjectState(phi.valueAt(i2)).getEntry(i)); + afterMergeEffects.addPhiInput(phis[i], getObjectState(states.get(i2), phi.valueAt(i2)).getEntry(i)); } } mergeEffects.addFloatingNode(virtual, "valueObjectNode"); newState.addObject(virtual, new ObjectState(virtual, Arrays.copyOf(phis, phis.length, ValueNode[].class), EscapeState.Virtual, null)); - newState.addAndMarkAlias(virtual, virtual, usages); - newState.addAndMarkAlias(virtual, phi, usages); + addAndMarkAlias(virtual, virtual); + addAndMarkAlias(virtual, phi); } else { materialize = true; } @@ -493,7 +498,7 @@ if (materialize) { for (int i = 0; i < phi.valueCount(); i++) { ValueNode value = phi.valueAt(i); - ObjectState obj = states.get(i).getObjectState(value); + ObjectState obj = getObjectState(states.get(i), value); if (obj != null) { materialized |= obj.isVirtual(); Block predecessor = mergeBlock.getPredecessors().get(i); @@ -504,4 +509,39 @@ return materialized; } } + + public ObjectState getObjectState(PartialEscapeBlockState state, ValueNode value) { + if (value == null) { + return null; + } + if (value.isAlive() && !aliases.isNew(value)) { + ValueNode object = aliases.get(value); + return object instanceof VirtualObjectNode ? state.getObjectStateOptional((VirtualObjectNode) object) : null; + } else { + if (value instanceof VirtualObjectNode) { + return state.getObjectStateOptional((VirtualObjectNode) value); + } + return null; + } + } + + void addAndMarkAlias(VirtualObjectNode virtual, ValueNode node) { + if (node.isAlive()) { + aliases.set(node, virtual); + for (Node usage : node.usages()) { + markVirtualUsages(usage); + } + } + } + + private void markVirtualUsages(Node node) { + if (!usages.isNew(node)) { + usages.mark(node); + } + if (node instanceof VirtualState) { + for (Node usage : node.usages()) { + markVirtualUsages(usage); + } + } + } } diff -r 7a5182bd2175 -r 3aef4d88fbb9 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java Wed Oct 02 10:19:43 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java Wed Oct 02 13:18:25 2013 +0200 @@ -103,7 +103,6 @@ } public ReadEliminationBlockState(ReadEliminationBlockState other) { - super(other); readCache = new HashMap<>(other.readCache); } @@ -114,10 +113,7 @@ @Override public boolean equivalentTo(ReadEliminationBlockState other) { - if (!compareMapsNoSize(readCache, other.readCache)) { - return false; - } - return super.equivalentTo(other); + return compareMapsNoSize(readCache, other.readCache); } public void addCacheEntry(CacheEntry identifier, ValueNode value) { diff -r 7a5182bd2175 -r 3aef4d88fbb9 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Wed Oct 02 10:19:43 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Wed Oct 02 13:18:25 2013 +0200 @@ -61,7 +61,7 @@ ValueNode cachedValue = state.getCacheEntry(identifier); if (cachedValue != null) { effects.replaceAtUsages(load, cachedValue); - state.addScalarAlias(load, cachedValue); + addScalarAlias(load, cachedValue); deleted = true; } else { state.addCacheEntry(identifier, load); @@ -76,7 +76,7 @@ LoadCacheEntry identifier = new LoadCacheEntry(object, store.field()); ValueNode cachedValue = state.getCacheEntry(identifier); - ValueNode value = state.getScalarAlias(store.value()); + ValueNode value = getScalarAlias(store.value()); if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { effects.deleteFixedNode(store); deleted = true; @@ -94,7 +94,7 @@ ValueNode cachedValue = state.getCacheEntry(identifier); if (cachedValue != null) { effects.replaceAtUsages(read, cachedValue); - state.addScalarAlias(read, cachedValue); + addScalarAlias(read, cachedValue); deleted = true; } else { state.addCacheEntry(identifier, read); @@ -107,7 +107,7 @@ ReadCacheEntry identifier = new ReadCacheEntry(object, write.location()); ValueNode cachedValue = state.getCacheEntry(identifier); - ValueNode value = state.getScalarAlias(write.value()); + ValueNode value = getScalarAlias(write.value()); if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { effects.deleteFixedNode(write); deleted = true; diff -r 7a5182bd2175 -r 3aef4d88fbb9 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Wed Oct 02 10:19:43 2013 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java Wed Oct 02 13:18:25 2013 +0200 @@ -36,18 +36,18 @@ class VirtualizerToolImpl implements VirtualizerTool { - private final NodeBitMap usages; private final MetaAccessProvider metaAccess; private final Assumptions assumptions; + private final PartialEscapeClosure closure; - VirtualizerToolImpl(NodeBitMap usages, MetaAccessProvider metaAccess, Assumptions assumptions) { - this.usages = usages; + VirtualizerToolImpl(MetaAccessProvider metaAccess, Assumptions assumptions, PartialEscapeClosure closure) { this.metaAccess = metaAccess; this.assumptions = assumptions; + this.closure = closure; } private boolean deleted; - private PartialEscapeBlockState state; + private PartialEscapeBlockState state; private ValueNode current; private FixedNode position; private GraphEffectList effects; @@ -76,15 +76,15 @@ @Override public State getObjectState(ValueNode value) { - return state.getObjectState(value); + return closure.getObjectState(state, value); } @Override public void setVirtualEntry(State objectState, int index, ValueNode value) { ObjectState obj = (ObjectState) objectState; assert obj != null && obj.isVirtual() : "not virtual: " + obj; - ObjectState valueState = state.getObjectState(value); - ValueNode newValue = value; + ObjectState valueState = closure.getObjectState(state, value); + ValueNode newValue; if (valueState == null) { newValue = getReplacedValue(value); assert obj.getEntry(index) == null || obj.getEntry(index).kind() == newValue.kind() || (isObjectEntry(obj.getEntry(index)) && isObjectEntry(newValue)); @@ -106,12 +106,12 @@ @Override public ValueNode getReplacedValue(ValueNode original) { - return state.getScalarAlias(original); + return closure.getScalarAlias(original); } @Override public void replaceWithVirtual(VirtualObjectNode virtual) { - state.addAndMarkAlias(virtual, current, usages); + closure.addAndMarkAlias(virtual, current); if (current instanceof FixedWithNextNode) { effects.deleteFixedNode((FixedWithNextNode) current); } @@ -120,8 +120,8 @@ @Override public void replaceWithValue(ValueNode replacement) { - effects.replaceAtUsages(current, state.getScalarAlias(replacement)); - state.addScalarAlias(current, replacement); + effects.replaceAtUsages(current, closure.getScalarAlias(replacement)); + closure.addScalarAlias(current, replacement); deleted = true; } @@ -148,16 +148,21 @@ @Override public void createVirtualObject(VirtualObjectNode virtualObject, ValueNode[] entryState, int[] locks) { VirtualUtil.trace("{{%s}} ", current); - if (virtualObject.isAlive()) { - state.addAndMarkAlias(virtualObject, virtualObject, usages); - } else { + if (!virtualObject.isAlive()) { effects.addFloatingNode(virtualObject, "newVirtualObject"); } for (int i = 0; i < entryState.length; i++) { - entryState[i] = state.getScalarAlias(entryState[i]); + if (!(entryState[i] instanceof VirtualObjectNode)) { + ObjectState v = closure.getObjectState(state, entryState[i]); + if (v != null) { + entryState[i] = v.isVirtual() ? v.getVirtualObject() : v.getMaterializedValue(); + } else { + entryState[i] = closure.getScalarAlias(entryState[i]); + } + } } state.addObject(virtualObject, new ObjectState(virtualObject, entryState, EscapeState.Virtual, locks)); - state.addAndMarkAlias(virtualObject, virtualObject, usages); + closure.addAndMarkAlias(virtualObject, virtualObject); PartialEscapeClosure.METRIC_ALLOCATION_REMOVED.increment(); }