comparison graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java @ 19359:afe80ca4b0f0

cache EscapeObjectStates during PEA
author Lukas Stadler <lukas.stadler@oracle.com>
date Fri, 13 Feb 2015 17:42:58 +0100
parents 8ab925a6f724
children fc104173384d
comparison
equal deleted inserted replaced
19358:5ea169a3bf81 19359:afe80ca4b0f0
36 import com.oracle.graal.nodes.extended.*; 36 import com.oracle.graal.nodes.extended.*;
37 import com.oracle.graal.nodes.spi.*; 37 import com.oracle.graal.nodes.spi.*;
38 import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; 38 import com.oracle.graal.nodes.spi.Virtualizable.EscapeState;
39 import com.oracle.graal.nodes.virtual.*; 39 import com.oracle.graal.nodes.virtual.*;
40 import com.oracle.graal.phases.schedule.*; 40 import com.oracle.graal.phases.schedule.*;
41 import com.oracle.graal.virtual.nodes.*;
42 41
43 public abstract class PartialEscapeClosure<BlockT extends PartialEscapeBlockState<BlockT>> extends EffectsClosure<BlockT> { 42 public abstract class PartialEscapeClosure<BlockT extends PartialEscapeBlockState<BlockT>> extends EffectsClosure<BlockT> {
44 43
45 public static final DebugMetric METRIC_MATERIALIZATIONS = Debug.metric("Materializations"); 44 public static final DebugMetric METRIC_MATERIALIZATIONS = Debug.metric("Materializations");
46 public static final DebugMetric METRIC_MATERIALIZATIONS_PHI = Debug.metric("MaterializationsPhi"); 45 public static final DebugMetric METRIC_MATERIALIZATIONS_PHI = Debug.metric("MaterializationsPhi");
160 FrameState frameState = getUniqueFramestate(nodeWithState, fs); 159 FrameState frameState = getUniqueFramestate(nodeWithState, fs);
161 Set<ObjectState> virtual = new ArraySet<>(); 160 Set<ObjectState> virtual = new ArraySet<>();
162 frameState.applyToNonVirtual(new CollectVirtualObjectsClosure(virtual, effects, state)); 161 frameState.applyToNonVirtual(new CollectVirtualObjectsClosure(virtual, effects, state));
163 collectLockedVirtualObjects(state, virtual); 162 collectLockedVirtualObjects(state, virtual);
164 collectReferencedVirtualObjects(state, virtual); 163 collectReferencedVirtualObjects(state, virtual);
165 addVirtualMappings(state, effects, frameState, virtual); 164 addVirtualMappings(effects, frameState, virtual);
166 } 165 }
167 } 166 }
168 167
169 private static FrameState getUniqueFramestate(NodeWithState nodeWithState, FrameState frameState) { 168 private static FrameState getUniqueFramestate(NodeWithState nodeWithState, FrameState frameState) {
170 if (frameState.getUsageCount() > 1) { 169 if (frameState.getUsageCount() > 1) {
174 return copy; 173 return copy;
175 } 174 }
176 return frameState; 175 return frameState;
177 } 176 }
178 177
179 private void addVirtualMappings(final BlockT state, final GraphEffectList effects, FrameState frameState, Set<ObjectState> virtual) { 178 private static void addVirtualMappings(GraphEffectList effects, FrameState frameState, Set<ObjectState> virtual) {
180 for (ObjectState obj : virtual) { 179 for (ObjectState obj : virtual) {
181 EscapeObjectState v; 180 effects.addVirtualMapping(frameState, obj.createEscapeObjectState());
182 if (obj.isVirtual()) {
183 v = createVirtualObjectState(state, obj);
184 } else {
185 v = new MaterializedObjectState(obj.virtual, obj.getMaterializedValue());
186 }
187 effects.addVirtualMapping(frameState, v);
188 } 181 }
189 } 182 }
190 183
191 private void collectReferencedVirtualObjects(final BlockT state, final Set<ObjectState> virtual) { 184 private void collectReferencedVirtualObjects(final BlockT state, final Set<ObjectState> virtual) {
192 ArrayDeque<ObjectState> queue = new ArrayDeque<>(virtual); 185 ArrayDeque<ObjectState> queue = new ArrayDeque<>(virtual);
204 } 197 }
205 } 198 }
206 } 199 }
207 } 200 }
208 201
209 private EscapeObjectState createVirtualObjectState(final BlockT state, ObjectState obj) { 202 private void collectLockedVirtualObjects(final BlockT state, Set<ObjectState> virtual) {
210 EscapeObjectState v;
211 ValueNode[] fieldState = obj.getEntries().clone();
212 for (int i = 0; i < fieldState.length; i++) {
213 ObjectState valueObj = getObjectState(state, fieldState[i]);
214 if (valueObj != null) {
215 if (valueObj.isVirtual()) {
216 fieldState[i] = valueObj.virtual;
217 } else {
218 fieldState[i] = valueObj.getMaterializedValue();
219 }
220 }
221 }
222 v = new VirtualObjectState(obj.virtual, fieldState);
223 return v;
224 }
225
226 private void collectLockedVirtualObjects(final BlockT state, final Set<ObjectState> virtual) {
227 for (ObjectState obj : state.getStates()) { 203 for (ObjectState obj : state.getStates()) {
228 if (obj.isVirtual() && obj.hasLocks()) { 204 if (obj.isVirtual() && obj.hasLocks()) {
229 virtual.add(obj); 205 virtual.add(obj);
230 } 206 }
231 } 207 }
237 private boolean ensureMaterialized(BlockT state, ObjectState obj, FixedNode materializeBefore, GraphEffectList effects, DebugMetric metric) { 213 private boolean ensureMaterialized(BlockT state, ObjectState obj, FixedNode materializeBefore, GraphEffectList effects, DebugMetric metric) {
238 assert obj != null; 214 assert obj != null;
239 if (obj.getState() == EscapeState.Virtual) { 215 if (obj.getState() == EscapeState.Virtual) {
240 metric.increment(); 216 metric.increment();
241 state.materializeBefore(materializeBefore, obj.virtual, EscapeState.Materialized, effects); 217 state.materializeBefore(materializeBefore, obj.virtual, EscapeState.Materialized, effects);
218 updateStatesForMaterialized(state, obj);
242 assert !obj.isVirtual(); 219 assert !obj.isVirtual();
243 return true; 220 return true;
244 } else { 221 } else {
245 assert obj.getState() == EscapeState.Materialized; 222 assert obj.getState() == EscapeState.Materialized;
246 return false; 223 return false;
224 }
225 }
226
227 private static void updateStatesForMaterialized(PartialEscapeBlockState<?> state, ObjectState obj) {
228 // update all existing states with the newly materialized object
229 for (ObjectState objState : state.objectStates.values()) {
230 if (objState.isVirtual()) {
231 ValueNode[] entries = objState.getEntries();
232 for (int i = 0; i < entries.length; i++) {
233 if (entries[i] == obj.virtual) {
234 objState.setEntry(i, obj.getMaterializedValue());
235 }
236 }
237 }
247 } 238 }
248 } 239 }
249 240
250 private boolean replaceWithMaterialized(Node value, Node usage, FixedNode materializeBefore, BlockT state, ObjectState obj, GraphEffectList effects, DebugMetric metric) { 241 private boolean replaceWithMaterialized(Node value, Node usage, FixedNode materializeBefore, BlockT state, ObjectState obj, GraphEffectList effects, DebugMetric metric) {
251 boolean materialized = ensureMaterialized(state, obj, materializeBefore, effects, metric); 242 boolean materialized = ensureMaterialized(state, obj, materializeBefore, effects, metric);
536 // virtual objects are compatible: create phis for all entries that need them 527 // virtual objects are compatible: create phis for all entries that need them
537 PhiNode[] phis = getValuePhis(object, object.entryCount()); 528 PhiNode[] phis = getValuePhis(object, object.entryCount());
538 int valueIndex = 0; 529 int valueIndex = 0;
539 while (valueIndex < values.length) { 530 while (valueIndex < values.length) {
540 for (int i = 1; i < objStates.length; i++) { 531 for (int i = 1; i < objStates.length; i++) {
541 ValueNode[] fields = objStates[i].getEntries(); 532 ValueNode field = objStates[i].getEntry(valueIndex);
542 if (phis[valueIndex] == null && values[valueIndex] != fields[valueIndex]) { 533 if (phis[valueIndex] == null && values[valueIndex] != field) {
543 phis[valueIndex] = new ValuePhiNode(values[valueIndex].stamp().unrestricted(), merge); 534 phis[valueIndex] = new ValuePhiNode(values[valueIndex].stamp().unrestricted(), merge);
544 } 535 }
545 } 536 }
546 if (phis[valueIndex] != null && !phis[valueIndex].stamp().isCompatible(values[valueIndex].stamp())) { 537 if (phis[valueIndex] != null && !phis[valueIndex].stamp().isCompatible(values[valueIndex].stamp())) {
547 phis[valueIndex] = new ValuePhiNode(values[valueIndex].stamp().unrestricted(), merge); 538 phis[valueIndex] = new ValuePhiNode(values[valueIndex].stamp().unrestricted(), merge);
594 boolean materialized = false; 585 boolean materialized = false;
595 for (int i = 0; i < objStates.length; i++) { 586 for (int i = 0; i < objStates.length; i++) {
596 if (!objStates[i].isVirtual()) { 587 if (!objStates[i].isVirtual()) {
597 break; 588 break;
598 } 589 }
599 ValueNode[] entries = objStates[i].getEntries(); 590 ValueNode entry = objStates[i].getEntry(entryIndex);
600 if (entries[entryIndex] instanceof VirtualObjectNode) { 591 if (entry instanceof VirtualObjectNode) {
601 ObjectState obj = blockStates.get(i).getObjectState((VirtualObjectNode) entries[entryIndex]); 592 ObjectState obj = blockStates.get(i).getObjectState((VirtualObjectNode) entry);
602 Block predecessor = mergeBlock.getPredecessors().get(i); 593 Block predecessor = mergeBlock.getPredecessors().get(i);
603 materialized |= ensureMaterialized(blockStates.get(i), obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_MERGE); 594 materialized |= ensureMaterialized(blockStates.get(i), obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_MERGE);
604 entries[entryIndex] = obj.getMaterializedValue(); 595 if (objStates[i].isVirtual()) {
605 } 596 objStates[i].setEntry(entryIndex, entry = obj.getMaterializedValue());
606 afterMergeEffects.addPhiInput(phi, entries[entryIndex]); 597 }
598 }
599 afterMergeEffects.addPhiInput(phi, entry);
607 } 600 }
608 return materialized; 601 return materialized;
609 } 602 }
610 603
611 /** 604 /**
615 private void mergePrimitiveEntry(ObjectState[] objStates, PhiNode phi, int entryIndex) { 608 private void mergePrimitiveEntry(ObjectState[] objStates, PhiNode phi, int entryIndex) {
616 for (ObjectState state : objStates) { 609 for (ObjectState state : objStates) {
617 if (!state.isVirtual()) { 610 if (!state.isVirtual()) {
618 break; 611 break;
619 } 612 }
620 afterMergeEffects.addPhiInput(phi, state.getEntries()[entryIndex]); 613 afterMergeEffects.addPhiInput(phi, state.getEntry(entryIndex));
621 } 614 }
622 } 615 }
623 616
624 /** 617 /**
625 * Examine a PhiNode and try to replace it with merging of virtual objects if all its inputs 618 * Examine a PhiNode and try to replace it with merging of virtual objects if all its inputs