optimizations
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2879 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
4dd7972a30
commit
3a3c9afaca
|
@ -572,10 +572,15 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
protected final PointerKeyAndState queriedPkAndState;
|
||||
|
||||
/**
|
||||
* set of variables whose points-to sets were queried
|
||||
* map from pointer key to states in which the key's points-to set was queried
|
||||
*/
|
||||
private final MultiMap<PointerKey, State> pointsToQueried = HashSetMultiMap.make();
|
||||
|
||||
/**
|
||||
* map from pointer key to states in which a tracked points-to set for the key was computed
|
||||
*/
|
||||
private final MultiMap<PointerKey, State> trackedQueried = HashSetMultiMap.make();
|
||||
|
||||
/**
|
||||
* forward worklist: for initially processing points-to queries
|
||||
*/
|
||||
|
@ -808,17 +813,14 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
Assertions._assert(label.isBarred());
|
||||
}
|
||||
final State curState = curPkAndState.getState();
|
||||
// TODO may need to speed this up with another data structure
|
||||
for (PointerKeyAndState pkAndState : pkToTrackedSet.keySet()) {
|
||||
if (succPk.equals(pkAndState.getPointerKey())) {
|
||||
State transState = stateMachine.transition(pkAndState.getState(), label);
|
||||
if (transState.equals(curState)) {
|
||||
ret.add(pkAndState);
|
||||
}
|
||||
Set<State> succPkStates = trackedQueried.get(succPk);
|
||||
for (State succState : succPkStates) {
|
||||
State transState = stateMachine.transition(succState, label);
|
||||
if (transState.equals(curState)) {
|
||||
ret.add(new PointerKeyAndState(succPk, succState));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
void handleBackCopy(PointerKeyAndState curPkAndState, PointerKey predPk, IFlowLabel label) {
|
||||
|
@ -879,6 +881,7 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
if (DEBUG) {
|
||||
// System.err.println("adding to tracked points-to " + pkAndState);
|
||||
}
|
||||
trackedQueried.put(pkAndState.getPointerKey(), pkAndState.getState());
|
||||
trackedPointsToWorklist.add(pkAndState);
|
||||
}
|
||||
|
||||
|
@ -2007,12 +2010,23 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
|
||||
private OrdinalSet<InstanceKeyAndState> getPToSetFromComputer(final PointsToComputer ptoComputer,
|
||||
PointerKeyAndState pointerKeyAndState) {
|
||||
// make sure relevant constraints have been added
|
||||
if (pointerKeyAndState.getPointerKey() instanceof LocalPointerKey) {
|
||||
LocalPointerKey lpk = (LocalPointerKey) pointerKeyAndState.getPointerKey();
|
||||
g.addSubgraphForNode(lpk.getNode());
|
||||
}
|
||||
// add pointerKeyAndState to init worklist
|
||||
ptoComputer.addToInitWorklist(pointerKeyAndState);
|
||||
// run worklist algorithm
|
||||
ptoComputer.worklistLoop();
|
||||
// suck out the points-to set
|
||||
return ptoComputer.makeOrdinalSet(ptoComputer.pkToP2Set.get(pointerKeyAndState));
|
||||
final MutableIntSet intP2Set = ptoComputer.pkToP2Set.get(pointerKeyAndState);
|
||||
if (intP2Set == null) {
|
||||
// null if empty p2set
|
||||
return OrdinalSet.empty();
|
||||
} else {
|
||||
return ptoComputer.makeOrdinalSet(intP2Set);
|
||||
}
|
||||
}
|
||||
|
||||
private void computeFlowsTo(PointsToComputer ptoComputer, OrdinalSet<InstanceKeyAndState> basePToSet) {
|
||||
|
@ -2028,13 +2042,20 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
private Collection<State> getFlowedToStates(PointsToComputer ptoComputer, OrdinalSet<InstanceKeyAndState> basePToSet,
|
||||
PointerKey putfieldBase) {
|
||||
Collection<State> result = HashSetFactory.make();
|
||||
for (PointerKeyAndState pkAndState : ptoComputer.pkToTrackedSet.keySet()) {
|
||||
if (pkAndState.getPointerKey().equals(putfieldBase)) {
|
||||
if (ptoComputer.makeOrdinalSet(ptoComputer.pkToTrackedSet.get(pkAndState)).containsAny(basePToSet)) {
|
||||
result.add(pkAndState.getState());
|
||||
}
|
||||
Set<State> trackedStates = ptoComputer.trackedQueried.get(putfieldBase);
|
||||
for (State trackedState : trackedStates) {
|
||||
PointerKeyAndState pkAndState = new PointerKeyAndState(putfieldBase, trackedState);
|
||||
if (ptoComputer.makeOrdinalSet(ptoComputer.pkToTrackedSet.get(pkAndState)).containsAny(basePToSet)) {
|
||||
result.add(trackedState);
|
||||
}
|
||||
}
|
||||
// for (PointerKeyAndState pkAndState : ptoComputer.pkToTrackedSet.keySet()) {
|
||||
// if (pkAndState.getPointerKey().equals(putfieldBase)) {
|
||||
// if (ptoComputer.makeOrdinalSet(ptoComputer.pkToTrackedSet.get(pkAndState)).containsAny(basePToSet)) {
|
||||
// result.add(pkAndState.getState());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2140,7 +2161,13 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
|||
}
|
||||
|
||||
private Collection<Pair<PointerKey, PointerKey>> getBaseAndStored(MemoryAccess fieldWrite, IField field) {
|
||||
IR ir = fieldWrite.getNode().getIR();
|
||||
final CGNode node = fieldWrite.getNode();
|
||||
// an optimization; if node is not represented in our constraint graph, then we could not possibly
|
||||
// have discovered flow to the base pointer
|
||||
if (!g.hasSubgraphForNode(node)) {
|
||||
return null;
|
||||
}
|
||||
IR ir = node.getIR();
|
||||
PointerKey base = null, stored = null;
|
||||
if (field == ArrayContents.v()) {
|
||||
final SSAInstruction instruction = ir.getInstructions()[fieldWrite.getInstructionIndex()];
|
||||
|
|
|
@ -63,7 +63,7 @@ public class TunedFieldRefinementPolicy implements FieldRefinePolicy {
|
|||
|
||||
private boolean superOfAnyEncountered(IClass klass) {
|
||||
for (IClass toRefine : typesToRefine) {
|
||||
if (cha.isAssignableFrom(klass, toRefine)) {
|
||||
if (cha.isAssignableFrom(klass, toRefine) || cha.isAssignableFrom(toRefine, klass)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
|
||||
package com.ibm.wala.demandpa.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -29,7 +29,6 @@ import com.ibm.wala.ipa.slicer.Statement;
|
|||
import com.ibm.wala.ipa.slicer.Slicer.ControlDependenceOptions;
|
||||
import com.ibm.wala.ipa.slicer.Slicer.DataDependenceOptions;
|
||||
import com.ibm.wala.ipa.slicer.thin.CISlicer;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.collections.MapUtil;
|
||||
import com.ibm.wala.util.debug.Assertions;
|
||||
import com.ibm.wala.util.debug.Trace;
|
||||
|
@ -70,19 +69,19 @@ public class PABasedMemoryAccessMap implements MemoryAccessMap {
|
|||
}
|
||||
|
||||
public Collection<MemoryAccess> getArrayReads(PointerKey arrayRef) {
|
||||
Set<MemoryAccess> memAccesses = HashSetFactory.make();
|
||||
Collection<MemoryAccess> memAccesses = new ArrayList<MemoryAccess>();
|
||||
if (DEBUG) {
|
||||
Trace.println("looking at reads of array ref " + arrayRef);
|
||||
}
|
||||
for (InstanceKey ik : pa.getPointsToSet(arrayRef)) {
|
||||
PointerKey ack = heapModel.getPointerKeyForArrayContents(ik);
|
||||
memAccesses.addAll(convertStmtsToMemoryAccess(invRef.get(ack)));
|
||||
convertStmtsToMemoryAccess(invRef.get(ack), memAccesses);
|
||||
}
|
||||
return memAccesses;
|
||||
}
|
||||
|
||||
public Collection<MemoryAccess> getArrayWrites(PointerKey arrayRef) {
|
||||
Set<MemoryAccess> memAccesses = HashSetFactory.make();
|
||||
Collection<MemoryAccess> memAccesses = new ArrayList<MemoryAccess>();
|
||||
if (DEBUG) {
|
||||
Trace.println("looking at writes to array ref " + arrayRef);
|
||||
}
|
||||
|
@ -91,56 +90,58 @@ public class PABasedMemoryAccessMap implements MemoryAccessMap {
|
|||
Trace.println("instance key " + ik + " class " + ik.getClass());
|
||||
}
|
||||
PointerKey ack = heapModel.getPointerKeyForArrayContents(ik);
|
||||
memAccesses.addAll(convertStmtsToMemoryAccess(invMod.get(ack)));
|
||||
convertStmtsToMemoryAccess(invMod.get(ack), memAccesses);
|
||||
}
|
||||
return memAccesses;
|
||||
}
|
||||
|
||||
public Collection<MemoryAccess> getFieldReads(PointerKey baseRef, IField field) {
|
||||
Set<MemoryAccess> memAccesses = HashSetFactory.make();
|
||||
Collection<MemoryAccess> memAccesses = new ArrayList<MemoryAccess>();
|
||||
for (InstanceKey ik : pa.getPointsToSet(baseRef)) {
|
||||
PointerKey ifk = heapModel.getPointerKeyForInstanceField(ik, field);
|
||||
memAccesses.addAll(convertStmtsToMemoryAccess(invRef.get(ifk)));
|
||||
convertStmtsToMemoryAccess(invRef.get(ifk), memAccesses);
|
||||
}
|
||||
return memAccesses;
|
||||
}
|
||||
|
||||
public Collection<MemoryAccess> getFieldWrites(PointerKey baseRef, IField field) {
|
||||
Set<MemoryAccess> memAccesses = HashSetFactory.make();
|
||||
Collection<MemoryAccess> memAccesses = new ArrayList<MemoryAccess>();
|
||||
for (InstanceKey ik : pa.getPointsToSet(baseRef)) {
|
||||
PointerKey ifk = heapModel.getPointerKeyForInstanceField(ik, field);
|
||||
memAccesses.addAll(convertStmtsToMemoryAccess(invMod.get(ifk)));
|
||||
convertStmtsToMemoryAccess(invMod.get(ifk), memAccesses);
|
||||
}
|
||||
return memAccesses;
|
||||
}
|
||||
|
||||
public Collection<MemoryAccess> getStaticFieldReads(IField field) {
|
||||
return convertStmtsToMemoryAccess(invRef.get(heapModel.getPointerKeyForStaticField(field)));
|
||||
Collection<MemoryAccess> result = new ArrayList<MemoryAccess>();
|
||||
convertStmtsToMemoryAccess(invRef.get(heapModel.getPointerKeyForStaticField(field)), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection<MemoryAccess> getStaticFieldWrites(IField field) {
|
||||
return convertStmtsToMemoryAccess(invMod.get(heapModel.getPointerKeyForStaticField(field)));
|
||||
Collection<MemoryAccess> result = new ArrayList<MemoryAccess>();
|
||||
convertStmtsToMemoryAccess(invMod.get(heapModel.getPointerKeyForStaticField(field)), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Collection<MemoryAccess> convertStmtsToMemoryAccess(Collection<Statement> stmts) {
|
||||
private void convertStmtsToMemoryAccess(Collection<Statement> stmts, Collection<MemoryAccess> result) {
|
||||
if (stmts == null) {
|
||||
return Collections.emptySet();
|
||||
return;
|
||||
}
|
||||
if (DEBUG) {
|
||||
Trace.println("statements: " + stmts);
|
||||
}
|
||||
Collection<MemoryAccess> ret = HashSetFactory.make();
|
||||
for (Statement s : stmts) {
|
||||
switch (s.getKind()) {
|
||||
case NORMAL:
|
||||
NormalStatement normStmt = (NormalStatement) s;
|
||||
ret.add(new MemoryAccess(normStmt.getInstructionIndex(), normStmt.getNode()));
|
||||
result.add(new MemoryAccess(normStmt.getInstructionIndex(), normStmt.getNode()));
|
||||
break;
|
||||
default:
|
||||
Assertions.UNREACHABLE();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public HeapModel getHeapModel() {
|
||||
|
|
Loading…
Reference in New Issue