Mercurial > hg > truffle
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 |