From 2299d8a13af9637532b43c073f9d1c2c9bf37cf8 Mon Sep 17 00:00:00 2001 From: Manu Sridharan Date: Tue, 17 Jul 2012 12:11:55 -0700 Subject: [PATCH] improve caching of receiver values when handling dispatch --- .../SSAPropagationCallGraphBuilder.java | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/SSAPropagationCallGraphBuilder.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/SSAPropagationCallGraphBuilder.java index 5d753f90b..dde349aeb 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/SSAPropagationCallGraphBuilder.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/SSAPropagationCallGraphBuilder.java @@ -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); }