improve caching of receiver values when handling dispatch

This commit is contained in:
Manu Sridharan 2012-07-17 12:11:55 -07:00
parent 9847bf21f4
commit 2299d8a13a
1 changed files with 19 additions and 8 deletions

View File

@ -1601,7 +1601,9 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
@Override
public byte evaluate(PointsToSetVariable lhs, final PointsToSetVariable[] rhs) {
assert dispatchIndices.length >= rhs.length : "bad operator at " + call;
final MutableBoolean sideEffect = new MutableBoolean();
// did evaluating the dispatch operation add a new possible target
// to the call site?
final MutableBoolean addedNewTarget = new MutableBoolean();
final MutableIntSet receiverVals;
if (constParams != null && constParams[0] != null) {
@ -1636,6 +1638,10 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
// keep separate rhsIndex, since it doesn't advance for constant
// parameters
int rhsIndex = (constParams != null && constParams[0] != null)? 0: 1;
// this flag is set to true if we ever call handleAllReceivers() in the
// loop below. we need to catch the case where we have a new receiver, but
// there are no other dispatch indices with new values
boolean propagatedReceivers = false;
// we start at index 1 since we need to handle the receiver specially; see
// below
for (int index = 1; index < dispatchIndices.length; index++) {
@ -1652,7 +1658,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
if (newReceiver || prevAtIndex.isEmpty()) {
for(int i = 0; i < constParams[paramIndex].length; i++) {
keys[paramIndex] = constParams[paramIndex][i];
handleAllReceivers(receiverVals,keys, sideEffect);
handleAllReceivers(receiverVals,keys, addedNewTarget);
propagatedReceivers = true;
int ii = system.instanceKeys.getMappedIndex(constParams[paramIndex][i]);
prevAtIndex.add(ii);
}
@ -1665,7 +1672,8 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
int ptr = ptrs.next();
if (newReceiver || !prevAtIndex.contains(ptr)) {
keys[paramIndex] = system.getInstanceKey(ptr);
handleAllReceivers(receiverVals,keys, sideEffect);
handleAllReceivers(receiverVals,keys, addedNewTarget);
propagatedReceivers = true;
prevAtIndex.add(ptr);
}
}
@ -1674,14 +1682,17 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap
}
keys[paramIndex] = null;
}
if (newReceiver && !sideEffect.b) {
// we have a new receiver value, and it wasn't propagated at all,
// so propagate it now
handleAllReceivers(receiverVals, keys, sideEffect);
if (newReceiver) {
if (!propagatedReceivers) {
// we have a new receiver value, and it wasn't propagated at all,
// so propagate it now
handleAllReceivers(receiverVals, keys, addedNewTarget);
}
// update receiver cache
previousPtrs[0].addAll(receiverVals);
}
byte sideEffectMask = sideEffect.b ? (byte) SIDE_EFFECT_MASK : 0;
byte sideEffectMask = addedNewTarget.b ? (byte) SIDE_EFFECT_MASK : 0;
return (byte) (NOT_CHANGED | sideEffectMask);
}