optimizations
git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@2755 f5eafffb-2e1d-0410-98e4-8ec43c5233c4
This commit is contained in:
parent
0e13e78df8
commit
90a5719e5c
|
@ -171,7 +171,7 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
||||||
for (CGNode callee : cg) {
|
for (CGNode callee : cg) {
|
||||||
for (Iterator<? extends CGNode> predNodes = cg.getPredNodes(callee); predNodes.hasNext();) {
|
for (Iterator<? extends CGNode> predNodes = cg.getPredNodes(callee); predNodes.hasNext();) {
|
||||||
CGNode caller = predNodes.next();
|
CGNode caller = predNodes.next();
|
||||||
for (Iterator<CallSiteReference> iterator = cg.getPossibleSites(caller, callee); iterator.hasNext(); ) {
|
for (Iterator<CallSiteReference> iterator = cg.getPossibleSites(caller, callee); iterator.hasNext();) {
|
||||||
CallSiteReference site = iterator.next();
|
CallSiteReference site = iterator.next();
|
||||||
try {
|
try {
|
||||||
caller.getIR().getCalls(site);
|
caller.getIR().getCalls(site);
|
||||||
|
@ -181,7 +181,7 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
||||||
System.err.println(caller.getIR());
|
System.err.println(caller.getIR());
|
||||||
if (caller.getMethod() instanceof ShrikeBTMethod) {
|
if (caller.getMethod() instanceof ShrikeBTMethod) {
|
||||||
try {
|
try {
|
||||||
Instruction[] instructions = ((ShrikeBTMethod)caller.getMethod()).getInstructions();
|
Instruction[] instructions = ((ShrikeBTMethod) caller.getMethod()).getInstructions();
|
||||||
for (int i = 0; i < instructions.length; i++) {
|
for (int i = 0; i < instructions.length; i++) {
|
||||||
System.err.println(i + ": " + instructions[i]);
|
System.err.println(i + ": " + instructions[i]);
|
||||||
}
|
}
|
||||||
|
@ -726,7 +726,9 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
||||||
if (pointsToQueried.put(pkAndState.getPointerKey(), pkAndState.getState())) {
|
if (pointsToQueried.put(pkAndState.getPointerKey(), pkAndState.getState())) {
|
||||||
if (Assertions.verifyAssertions && pkAndState.getPointerKey() instanceof LocalPointerKey) {
|
if (Assertions.verifyAssertions && pkAndState.getPointerKey() instanceof LocalPointerKey) {
|
||||||
CGNode node = ((LocalPointerKey) pkAndState.getPointerKey()).getNode();
|
CGNode node = ((LocalPointerKey) pkAndState.getPointerKey()).getNode();
|
||||||
Assertions._assert(g.hasSubgraphForNode(node), "missing constraints for node of var " + pkAndState);
|
if (!g.hasSubgraphForNode(node)) {
|
||||||
|
Assertions._assert(false, "missing constraints for node of var " + pkAndState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
// System.err.println("adding to init_ " + pkAndState);
|
// System.err.println("adding to init_ " + pkAndState);
|
||||||
|
@ -743,7 +745,9 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
||||||
protected void addToTrackedPToWorklist(PointerKeyAndState pkAndState) {
|
protected void addToTrackedPToWorklist(PointerKeyAndState pkAndState) {
|
||||||
if (Assertions.verifyAssertions && pkAndState.getPointerKey() instanceof LocalPointerKey) {
|
if (Assertions.verifyAssertions && pkAndState.getPointerKey() instanceof LocalPointerKey) {
|
||||||
CGNode node = ((LocalPointerKey) pkAndState.getPointerKey()).getNode();
|
CGNode node = ((LocalPointerKey) pkAndState.getPointerKey()).getNode();
|
||||||
Assertions._assert(g.hasSubgraphForNode(node), "missing constraints for " + node);
|
if (!g.hasSubgraphForNode(node)) {
|
||||||
|
Assertions._assert(false, "missing constraints for " + node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
// System.err.println("adding to tracked points-to " + pkAndState);
|
// System.err.println("adding to tracked points-to " + pkAndState);
|
||||||
|
@ -1596,7 +1600,9 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
||||||
// System.err.println("ASSERTION WILL FAIL");
|
// System.err.println("ASSERTION WILL FAIL");
|
||||||
// System.err.println("QUERIED: " + queriedPkAndStates);
|
// System.err.println("QUERIED: " + queriedPkAndStates);
|
||||||
// }
|
// }
|
||||||
Assertions._assert(basePointerOkay, "queried " + loadedValAndState + " but not " + baseAndStateToHandle);
|
if (!basePointerOkay) {
|
||||||
|
Assertions._assert(false, "queried " + loadedValAndState + " but not " + baseAndStateToHandle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
final IntSet curP2Set = find(pkToP2Set, baseAndStateToHandle);
|
final IntSet curP2Set = find(pkToP2Set, baseAndStateToHandle);
|
||||||
// int startSize = curP2Set.size();
|
// int startSize = curP2Set.size();
|
||||||
|
@ -1662,6 +1668,11 @@ public class DemandRefinementPointsTo extends AbstractDemandPointsTo {
|
||||||
return node.getIR();
|
return node.getIR();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private SSAAbstractInvokeInstruction[] getCallInstrs(CGNode node, CallSiteReference site) {
|
||||||
|
return node.getIR().getCalls(site);
|
||||||
|
}
|
||||||
|
|
||||||
private Object doTransition(State curState, IFlowLabel label, Function<State, Object> func) {
|
private Object doTransition(State curState, IFlowLabel label, Function<State, Object> func) {
|
||||||
State nextState = stateMachine.transition(curState, label);
|
State nextState = stateMachine.transition(curState, label);
|
||||||
Object ret = null;
|
Object ret = null;
|
||||||
|
|
|
@ -40,6 +40,7 @@ package com.ibm.wala.demandpa.flowgraph;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.ibm.wala.cfg.ControlFlowGraph;
|
import com.ibm.wala.cfg.ControlFlowGraph;
|
||||||
|
@ -64,6 +65,7 @@ import com.ibm.wala.ssa.SSAInstruction;
|
||||||
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
import com.ibm.wala.ssa.SSAInvokeInstruction;
|
||||||
import com.ibm.wala.ssa.SSAPhiInstruction;
|
import com.ibm.wala.ssa.SSAPhiInstruction;
|
||||||
import com.ibm.wala.util.collections.EmptyIterator;
|
import com.ibm.wala.util.collections.EmptyIterator;
|
||||||
|
import com.ibm.wala.util.collections.HashMapFactory;
|
||||||
import com.ibm.wala.util.collections.HashSetFactory;
|
import com.ibm.wala.util.collections.HashSetFactory;
|
||||||
import com.ibm.wala.util.debug.Assertions;
|
import com.ibm.wala.util.debug.Assertions;
|
||||||
import com.ibm.wala.util.debug.Trace;
|
import com.ibm.wala.util.debug.Trace;
|
||||||
|
@ -77,7 +79,7 @@ import com.ibm.wala.util.ref.ReferenceCleanser;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractDemandFlowGraph extends AbstractFlowGraph {
|
public abstract class AbstractDemandFlowGraph extends AbstractFlowGraph {
|
||||||
private final static boolean DEBUG = true;
|
private final static boolean DEBUG = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Counter for wiping soft caches
|
* Counter for wiping soft caches
|
||||||
|
@ -96,15 +98,16 @@ public abstract class AbstractDemandFlowGraph extends AbstractFlowGraph {
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
throw new IllegalArgumentException("node == null");
|
throw new IllegalArgumentException("node == null");
|
||||||
}
|
}
|
||||||
if (node.getIR() == null) {
|
IR ir = node.getIR();
|
||||||
|
if (ir == null) {
|
||||||
throw new IllegalArgumentException("no ir for node " + node);
|
throw new IllegalArgumentException("no ir for node " + node);
|
||||||
}
|
}
|
||||||
int n = cg.getNumber(node);
|
int n = cg.getNumber(node);
|
||||||
if (!cgNodesVisited.contains(n)) {
|
if (!cgNodesVisited.contains(n)) {
|
||||||
cgNodesVisited.add(n);
|
cgNodesVisited.add(n);
|
||||||
unconditionallyAddConstraintsFromNode(node);
|
unconditionallyAddConstraintsFromNode(node, ir);
|
||||||
addNodesForInvocations(node);
|
addNodesForInvocations(node, ir);
|
||||||
addNodesForParameters(node);
|
addNodesForParameters(node, ir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,9 +252,9 @@ public abstract class AbstractDemandFlowGraph extends AbstractFlowGraph {
|
||||||
return returnPreds.iterator();
|
return returnPreds.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void addNodesForParameters(CGNode node);
|
protected abstract void addNodesForParameters(CGNode node, IR ir);
|
||||||
|
|
||||||
protected void unconditionallyAddConstraintsFromNode(CGNode node) {
|
protected void unconditionallyAddConstraintsFromNode(CGNode node, IR ir) {
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Trace.println("Adding constraints for CGNode " + node);
|
Trace.println("Adding constraints for CGNode " + node);
|
||||||
|
@ -265,7 +268,6 @@ public abstract class AbstractDemandFlowGraph extends AbstractFlowGraph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IR ir = node.getIR();
|
|
||||||
debugPrintIR(ir);
|
debugPrintIR(ir);
|
||||||
|
|
||||||
if (ir == null) {
|
if (ir == null) {
|
||||||
|
@ -274,8 +276,8 @@ public abstract class AbstractDemandFlowGraph extends AbstractFlowGraph {
|
||||||
|
|
||||||
DefUse du = node.getDU();
|
DefUse du = node.getDU();
|
||||||
addNodeInstructionConstraints(node, ir, du);
|
addNodeInstructionConstraints(node, ir, du);
|
||||||
addNodePassthruExceptionConstraints(node);
|
addNodePassthruExceptionConstraints(node, ir);
|
||||||
addNodeConstantConstraints(node);
|
addNodeConstantConstraints(node, ir);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -364,22 +366,28 @@ public abstract class AbstractDemandFlowGraph extends AbstractFlowGraph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final Map<CGNode, Set<CallSiteAndCGNode>> callerCache = HashMapFactory.make();
|
||||||
|
|
||||||
public Set<CallSiteAndCGNode> getPotentialCallers(PointerKey formalPk) {
|
public Set<CallSiteAndCGNode> getPotentialCallers(PointerKey formalPk) {
|
||||||
CGNode callee = null;
|
CGNode callee = null;
|
||||||
if (formalPk instanceof LocalPointerKey) {
|
if (formalPk instanceof LocalPointerKey) {
|
||||||
callee = ((LocalPointerKey)formalPk).getNode();
|
callee = ((LocalPointerKey) formalPk).getNode();
|
||||||
} else if (formalPk instanceof ReturnValueKey) {
|
} else if (formalPk instanceof ReturnValueKey) {
|
||||||
callee = ((ReturnValueKey)formalPk).getNode();
|
callee = ((ReturnValueKey) formalPk).getNode();
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("formalPk must represent a local");
|
throw new IllegalArgumentException("formalPk must represent a local");
|
||||||
}
|
}
|
||||||
Set<CallSiteAndCGNode> ret = HashSetFactory.make();
|
Set<CallSiteAndCGNode> ret = callerCache.get(callee);
|
||||||
for (Iterator<? extends CGNode> predNodes = cg.getPredNodes(callee); predNodes.hasNext(); ) {
|
if (ret == null) {
|
||||||
CGNode caller = predNodes.next();
|
ret = HashSetFactory.make();
|
||||||
for (Iterator<CallSiteReference> iterator = cg.getPossibleSites(caller, callee); iterator.hasNext(); ) {
|
for (Iterator<? extends CGNode> predNodes = cg.getPredNodes(callee); predNodes.hasNext();) {
|
||||||
CallSiteReference call = iterator.next();
|
CGNode caller = predNodes.next();
|
||||||
ret.add(new CallSiteAndCGNode(call,caller));
|
for (Iterator<CallSiteReference> iterator = cg.getPossibleSites(caller, callee); iterator.hasNext();) {
|
||||||
|
CallSiteReference call = iterator.next();
|
||||||
|
ret.add(new CallSiteAndCGNode(call, caller));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
callerCache.put(callee, ret);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -393,7 +401,7 @@ public abstract class AbstractDemandFlowGraph extends AbstractFlowGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractDemandFlowGraph(final CallGraph cg, final HeapModel heapModel, final MemoryAccessMap mam, final ClassHierarchy cha) {
|
public AbstractDemandFlowGraph(final CallGraph cg, final HeapModel heapModel, final MemoryAccessMap mam, final ClassHierarchy cha) {
|
||||||
super(mam,heapModel,cha,cg);
|
super(mam, heapModel, cha, cg);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -169,8 +169,7 @@ public abstract class AbstractFlowGraph extends SlowSparseNumberedLabeledGraph<O
|
||||||
* For each invocation in the method, add nodes for actual parameters and return values
|
* For each invocation in the method, add nodes for actual parameters and return values
|
||||||
* @param node
|
* @param node
|
||||||
*/
|
*/
|
||||||
protected void addNodesForInvocations(CGNode node) {
|
protected void addNodesForInvocations(CGNode node, IR ir) {
|
||||||
final IR ir = node.getIR();
|
|
||||||
for (Iterator<CallSiteReference> iter = ir.iterateCallSites(); iter.hasNext(); ) {
|
for (Iterator<CallSiteReference> iter = ir.iterateCallSites(); iter.hasNext(); ) {
|
||||||
CallSiteReference site = iter.next();
|
CallSiteReference site = iter.next();
|
||||||
SSAAbstractInvokeInstruction[] calls = ir.getCalls(site);
|
SSAAbstractInvokeInstruction[] calls = ir.getCalls(site);
|
||||||
|
@ -380,10 +379,9 @@ public abstract class AbstractFlowGraph extends SlowSparseNumberedLabeledGraph<O
|
||||||
* Add constraints to represent the flow of exceptions to the exceptional
|
* Add constraints to represent the flow of exceptions to the exceptional
|
||||||
* return value for this node
|
* return value for this node
|
||||||
*/
|
*/
|
||||||
protected void addNodePassthruExceptionConstraints(CGNode node) {
|
protected void addNodePassthruExceptionConstraints(CGNode node, IR ir) {
|
||||||
// add constraints relating to thrown exceptions that reach the exit
|
// add constraints relating to thrown exceptions that reach the exit
|
||||||
// block.
|
// block.
|
||||||
IR ir = node.getIR();
|
|
||||||
List<ProgramCounter> peis = SSAPropagationCallGraphBuilder.getIncomingPEIs(ir, ir.getExitBlock());
|
List<ProgramCounter> peis = SSAPropagationCallGraphBuilder.getIncomingPEIs(ir, ir.getExitBlock());
|
||||||
PointerKey exception = heapModel.getPointerKeyForExceptionalReturnValue(node);
|
PointerKey exception = heapModel.getPointerKeyForExceptionalReturnValue(node);
|
||||||
|
|
||||||
|
@ -454,8 +452,7 @@ public abstract class AbstractFlowGraph extends SlowSparseNumberedLabeledGraph<O
|
||||||
/**
|
/**
|
||||||
* add constraints for reference constants assigned to vars
|
* add constraints for reference constants assigned to vars
|
||||||
*/
|
*/
|
||||||
protected void addNodeConstantConstraints(CGNode node) {
|
protected void addNodeConstantConstraints(CGNode node, IR ir) {
|
||||||
IR ir = node.getIR();
|
|
||||||
SymbolTable symbolTable = ir.getSymbolTable();
|
SymbolTable symbolTable = ir.getSymbolTable();
|
||||||
for (int i = 1; i <= symbolTable.getMaxValueNumber(); i++) {
|
for (int i = 1; i <= symbolTable.getMaxValueNumber(); i++) {
|
||||||
if (symbolTable.isConstant(i)) {
|
if (symbolTable.isConstant(i)) {
|
||||||
|
|
|
@ -102,7 +102,7 @@ public class DemandPointerFlowGraph extends AbstractDemandFlowGraph implements I
|
||||||
* @param node
|
* @param node
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void addNodesForParameters(CGNode node) {
|
protected void addNodesForParameters(CGNode node, IR ir) {
|
||||||
for (Iterator<Integer> iter = new PointerParamValueNumIterator(node); iter.hasNext();) {
|
for (Iterator<Integer> iter = new PointerParamValueNumIterator(node); iter.hasNext();) {
|
||||||
int parameter = iter.next();
|
int parameter = iter.next();
|
||||||
PointerKey paramPk = heapModel.getPointerKeyForLocal(node, parameter);
|
PointerKey paramPk = heapModel.getPointerKeyForLocal(node, parameter);
|
||||||
|
|
|
@ -98,8 +98,7 @@ public class DemandValueFlowGraph extends AbstractDemandFlowGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addNodesForParameters(CGNode node) {
|
protected void addNodesForParameters(CGNode node, IR ir) {
|
||||||
IR ir = node.getIR();
|
|
||||||
SymbolTable symbolTable = ir.getSymbolTable();
|
SymbolTable symbolTable = ir.getSymbolTable();
|
||||||
int numParams = symbolTable.getNumberOfParameters();
|
int numParams = symbolTable.getNumberOfParameters();
|
||||||
for (int i = 0; i < numParams; i++) {
|
for (int i = 0; i < numParams; i++) {
|
||||||
|
|
Loading…
Reference in New Issue