From fd1a1d4cae3e7c5004e7ee6f597edbf2d1b1e077 Mon Sep 17 00:00:00 2001 From: sjfink Date: Wed, 11 Jul 2007 16:24:58 +0000 Subject: [PATCH] restructure to allow CGNodes to dwell in more than one CallGraph. lift some functions up from CGNode to CallGraph git-svn-id: https://wala.svn.sourceforge.net/svnroot/wala/trunk@1422 f5eafffb-2e1d-0410-98e4-8ec43c5233c4 --- .../com/ibm/wala/emf/wrappers/EMFBridge.java | 2 +- .../com/ibm/wala/ipa/callgraph/CGNode.java | 47 ++++++------ .../com/ibm/wala/ipa/callgraph/CallGraph.java | 43 +++++++---- .../ipa/callgraph/impl/BasicCallGraph.java | 44 +---------- .../ipa/callgraph/impl/ExplicitCallGraph.java | 75 ++++++++++++++----- .../ipa/callgraph/impl/PartialCallGraph.java | 16 ++++ .../propagation/PointerAnalysisImpl.java | 4 +- .../propagation/PointerFlowGraph.java | 2 +- .../SSAPropagationCallGraphBuilder.java | 7 +- .../propagation/rta/AbstractRTABuilder.java | 1 + .../propagation/rta/BasicRTABuilder.java | 2 +- .../rta/DelegatingExplicitCallGraph.java | 8 +- .../ibm/wala/ipa/cfg/InterproceduralCFG.java | 9 +-- .../ibm/wala/ipa/slicer/HeapReachingDefs.java | 22 +++--- .../src/com/ibm/wala/ipa/slicer/PDG.java | 16 ++-- .../src/com/ibm/wala/ipa/slicer/SDG.java | 42 ++++++----- 16 files changed, 189 insertions(+), 151 deletions(-) diff --git a/com.ibm.wala.core/src/com/ibm/wala/emf/wrappers/EMFBridge.java b/com.ibm.wala.core/src/com/ibm/wala/emf/wrappers/EMFBridge.java index 904e2935a..7ae9e5f83 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/emf/wrappers/EMFBridge.java +++ b/com.ibm.wala.core/src/com/ibm/wala/emf/wrappers/EMFBridge.java @@ -65,7 +65,7 @@ public class EMFBridge { for (Iterator it2 = n.iterateSites(); it2.hasNext();) { CallSiteReference site = (CallSiteReference) it2.next(); ECallSite eSite = makeCallSite(method, site); - for (Iterator it3 = n.getPossibleTargets(site).iterator(); it3.hasNext();) { + for (Iterator it3 = cg.getPossibleTargets(n,site).iterator(); it3.hasNext();) { CGNode target = (CGNode) it3.next(); result.addEdge(eSite, makeJavaMethod(target.getMethod().getReference())); } diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/CGNode.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/CGNode.java index 5d57e219d..6e20d83d0 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/CGNode.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/CGNode.java @@ -11,7 +11,6 @@ package com.ibm.wala.ipa.callgraph; import java.util.Iterator; -import java.util.Set; import com.ibm.wala.cfg.ControlFlowGraph; import com.ibm.wala.classLoader.CallSiteReference; @@ -44,40 +43,44 @@ public interface CGNode extends INodeWithNumber, ContextItem { */ public Context getContext(); - /** - * Return the set of CGNodes that represent possible targets - * of a particular call site when invoked in this context. - */ - Set getPossibleTargets(CallSiteReference site); +// /** +// * Return the set of CGNodes that represent possible targets +// * of a particular call site when invoked in this context. +// */ +// Set getPossibleTargets(CallSiteReference site); /** * @return Iterator of CallSiteReference */ Iterator iterateSites(); +// /** +// * @param target +// * @return iterator of CallSiteReference, the call sites in this node that might +// * dispatch to the target node. +// */ +// Iterator getPossibleSites(CGNode target); +// /** - * @param target - * @return iterator of CallSiteReference, the call sites in this node that might - * dispatch to the target node. - */ - Iterator getPossibleSites(CGNode target); - - /** + * This is for use only by call graph builders ... not by the general + * public. Clients should not use this. + * * Record that a particular call site might resolve to a call to a * particular target node. Returns true if this is a new target */ + @Deprecated public boolean addTarget(CallSiteReference site, CGNode target); - /** - * @return the number of nodes that the call site current may resolve - * to - */ - public int getNumberOfTargets(CallSiteReference site); +// /** +// * @return the number of nodes that the call site current may resolve +// * to +// */ +// public int getNumberOfTargets(CallSiteReference site); - /** - * @return the call graph in which this node dwells - */ - public CallGraph getCallGraph(); +// /** +// * @return the call graph in which this node dwells +// */ +// public CallGraph getCallGraph(); /** * @return the "default" IR for this node used by the governing call graph diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/CallGraph.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/CallGraph.java index 47a69b6ab..8865524e0 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/CallGraph.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/CallGraph.java @@ -11,8 +11,10 @@ package com.ibm.wala.ipa.callgraph; import java.util.Collection; +import java.util.Iterator; import java.util.Set; +import com.ibm.wala.classLoader.CallSiteReference; import com.ibm.wala.classLoader.IMethod; import com.ibm.wala.ipa.cha.IClassHierarchy; import com.ibm.wala.types.MethodReference; @@ -21,15 +23,15 @@ import com.ibm.wala.util.graph.NumberedGraph; /** * Basic interface for a call graph, which is a graph of CGNode * - * + * * @author Stephen Fink */ public interface CallGraph extends NumberedGraph { /** - * Return the (fake) interprocedural {@link CGNode root node} - * of the call graph. - * + * Return the (fake) interprocedural {@link CGNode root node} of the call + * graph. + * * @return the "fake" root node the call graph */ public CGNode getFakeRootNode(); @@ -40,29 +42,40 @@ public interface CallGraph extends NumberedGraph { public Collection getEntrypointNodes(); /** - * If you want to get all the nodes corresponding to - * a particular method, regardless of context, then use - * {@link CGNode getNodes} + * If you want to get all the nodes corresponding to a particular + * method, regardless of context, then use {@link CGNode getNodes} * * @return the node corresponding a method in a context */ public CGNode getNode(IMethod method, Context C); /** - * @param m a method reference - * @return the set of all nodes in the call graph that represent - * this method. + * @param m + * a method reference + * @return the set of all nodes in the call graph that represent this method. */ public Set getNodes(MethodReference m); - /** - * Dump the callgraph to the specified file in dotty(1) format. - */ - public void dump(String filename); - /** * @return the governing class hierarchy for this call graph */ public IClassHierarchy getClassHierarchy(); + /** + * Return the set of CGNodes that represent possible targets of a particular + * call site from a particular node + */ + public Set getPossibleTargets(CGNode node, CallSiteReference site); + + /** + * @return the number of nodes that the call site may dispatch to + */ + public int getNumberOfTargets(CGNode node, CallSiteReference site); + + /** + * @return iterator of CallSiteReference, the call sites in a node that might + * dispatch to the target node. + */ + Iterator getPossibleSites(CGNode src, CGNode target); + } diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/BasicCallGraph.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/BasicCallGraph.java index d1c083600..4f7b03c79 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/BasicCallGraph.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/BasicCallGraph.java @@ -10,10 +10,6 @@ *******************************************************************************/ package com.ibm.wala.ipa.callgraph.impl; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintWriter; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -94,9 +90,7 @@ public abstract class BasicCallGraph extends AbstractNumberedGraph imple super(); } - /** - * - */ + @SuppressWarnings("deprecation") public void init() { fakeRoot = makeFakeRootNode(); Key k = new Key(fakeRoot.getMethod(), fakeRoot.getContext()); @@ -197,8 +191,6 @@ public abstract class BasicCallGraph extends AbstractNumberedGraph imple return method; } - public abstract Set getPossibleTargets(CallSiteReference site); - /** * @see java.lang.Object#equals(Object) */ @@ -236,7 +228,7 @@ public abstract class BasicCallGraph extends AbstractNumberedGraph imple if (n.getMethod() != null) { for (Iterator sites = n.iterateSites(); sites.hasNext();) { CallSiteReference site = (CallSiteReference) sites.next(); - Iterator targets = n.getPossibleTargets(site).iterator(); + Iterator targets = getPossibleTargets(n, site).iterator(); if (targets.hasNext()) { result.append(" - " + site + "\n"); } @@ -250,38 +242,6 @@ public abstract class BasicCallGraph extends AbstractNumberedGraph imple return result.toString(); } - /** - * Dump this callgraph to the specified file in dotty(1) format. - * @throws IllegalArgumentException if filename is null - */ - public void dump(String filename) { - if (filename == null) { - throw new IllegalArgumentException("filename is null"); - } - File file = new File(filename); - try { - PrintWriter out = new PrintWriter(new FileOutputStream(file)); - out.println("digraph callgraph {"); - for (Iterator it = iterator(); it.hasNext();) { - CGNode n = (CGNode) it.next(); - for (Iterator it2 = getSuccNodes(n); it2.hasNext();) { - CGNode m = (CGNode) it2.next(); - out.println(" \"" + prettyPrint(n) + "\" -> \"" + prettyPrint(m) + "\""); - } - } - out.println("}"); - out.close(); - } catch (IOException e) { - e.printStackTrace(); - Assertions.UNREACHABLE(); - } - } - - private String prettyPrint(CGNode n) { - String s = n.toString().replace(",", "\\n"); - return s.replace(" > Context: ", "\\n"); - } - @Override public void removeNodeAndEdges(CGNode N) { Assertions.UNREACHABLE(); diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/ExplicitCallGraph.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/ExplicitCallGraph.java index d646ae092..d2b217270 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/ExplicitCallGraph.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/ExplicitCallGraph.java @@ -146,8 +146,7 @@ public class ExplicitCallGraph extends BasicCallGraph implements BytecodeConstan super(method, C); } - @Override - public Set getPossibleTargets(CallSiteReference site) { + protected Set getPossibleTargets(CallSiteReference site) { Object result = targets.get(site.getProgramCounter()); if (result == null) { @@ -165,7 +164,7 @@ public class ExplicitCallGraph extends BasicCallGraph implements BytecodeConstan } } - public IntSet getPossibleTargetNumbers(CallSiteReference site) { + protected IntSet getPossibleTargetNumbers(CallSiteReference site) { Object t = targets.get(site.getProgramCounter()); if (t == null) { @@ -180,7 +179,7 @@ public class ExplicitCallGraph extends BasicCallGraph implements BytecodeConstan /* * @see com.ibm.wala.ipa.callgraph.CGNode#getPossibleSites(com.ibm.wala.ipa.callgraph.CGNode) */ - public Iterator getPossibleSites(final CGNode to) { + protected Iterator getPossibleSites(final CGNode to) { final int n = getCallGraph().getNumber(to); return new FilterIterator(iterateSites(), new Filter() { public boolean accepts(Object o) { @@ -189,6 +188,19 @@ public class ExplicitCallGraph extends BasicCallGraph implements BytecodeConstan } }); } + + + protected int getNumberOfTargets(CallSiteReference site) { + Object result = targets.get(site.getProgramCounter()); + + if (result == null) { + return 0; + } else if (result instanceof CGNode) { + return 1; + } else { + return ((IntSet) result).size(); + } + } @Override public boolean addTarget(CallSiteReference site, CGNode tNode) { @@ -229,20 +241,6 @@ public class ExplicitCallGraph extends BasicCallGraph implements BytecodeConstan } } - /* - * @see com.ibm.detox.ipa.callgraph.CGNode#getNumberOfTargets(com.ibm.wala.classLoader.CallSiteReference) - */ - public int getNumberOfTargets(CallSiteReference site) { - Object result = targets.get(site.getProgramCounter()); - - if (result == null) { - return 0; - } else if (result instanceof CGNode) { - return 1; - } else { - return ((IntSet) result).size(); - } - } /* * @see com.ibm.wala.ipa.callgraph.CGNode#iterateSites() @@ -295,7 +293,7 @@ public class ExplicitCallGraph extends BasicCallGraph implements BytecodeConstan return getMethod().hashCode() * 8681 + getContext().hashCode(); } - public MutableSharedBitVectorIntSet getAllTargetNumbers() { + protected MutableSharedBitVectorIntSet getAllTargetNumbers() { return allTargets; } @@ -441,4 +439,43 @@ public class ExplicitCallGraph extends BasicCallGraph implements BytecodeConstan protected ExplicitEdgeManager makeEdgeManger() { return new ExplicitEdgeManager(); } + + public int getNumberOfTargets(CGNode node, CallSiteReference site) { + if (!containsNode(node)) { + throw new IllegalArgumentException("node not in callgraph " + node); + } + assert (node instanceof ExplicitNode); + ExplicitNode n = (ExplicitNode)node; + return n.getNumberOfTargets(site); + } + + public Iterator getPossibleSites(CGNode src, CGNode target) { + if (!containsNode(src)) { + throw new IllegalArgumentException("node not in callgraph " + src); + } + if (!containsNode(target)) { + throw new IllegalArgumentException("node not in callgraph " + target); + } + assert (src instanceof ExplicitNode); + ExplicitNode n = (ExplicitNode)src; + return n.getPossibleSites(target); + } + + public Set getPossibleTargets(CGNode node, CallSiteReference site) { + if (!containsNode(node)) { + throw new IllegalArgumentException("node not in callgraph " + node); + } + assert (node instanceof ExplicitNode); + ExplicitNode n = (ExplicitNode)node; + return n.getPossibleTargets(site); + } + + public IntSet getPossibleTargetNumbers(CGNode node, CallSiteReference site) { + if (!containsNode(node)) { + throw new IllegalArgumentException("node not in callgraph " + node); + } + assert (node instanceof ExplicitNode); + ExplicitNode n = (ExplicitNode)node; + return n.getPossibleTargetNumbers(site); + } } diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/PartialCallGraph.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/PartialCallGraph.java index e90b9ef1e..7a8831cf6 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/PartialCallGraph.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/impl/PartialCallGraph.java @@ -4,6 +4,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.Set; +import com.ibm.wala.classLoader.CallSiteReference; import com.ibm.wala.classLoader.IMethod; import com.ibm.wala.ipa.callgraph.CGNode; import com.ibm.wala.ipa.callgraph.CallGraph; @@ -125,4 +126,19 @@ public class PartialCallGraph extends DelegatingGraph implements CallGra return x; } + + public int getNumberOfTargets(CGNode node, CallSiteReference site) { + Assertions.UNREACHABLE("TODO"); + return 0; + } + + public Iterator getPossibleSites(CGNode src, CGNode target) { + Assertions.UNREACHABLE("TODO"); + return null; + } + + public Set getPossibleTargets(CGNode node, CallSiteReference site) { + Assertions.UNREACHABLE("TODO"); + return null; + } } diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PointerAnalysisImpl.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PointerAnalysisImpl.java index 384952523..9bee9c1fb 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PointerAnalysisImpl.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PointerAnalysisImpl.java @@ -424,14 +424,12 @@ public class PointerAnalysisImpl extends AbstractPointerAnalysis { } /** - * @param node - * @param call * @return the points-to set for the exceptional return values from a * particular call site */ private OrdinalSet computeImplicitExceptionsForCall(CGNode node, SSAInvokeInstruction call) { MutableSparseIntSet S = new MutableSparseIntSet(); - for (Iterator it = node.getPossibleTargets(call.getCallSite()).iterator(); it.hasNext();) { + for (Iterator it = getCallGraph().getPossibleTargets(node, call.getCallSite()).iterator(); it.hasNext();) { CGNode target = (CGNode) it.next(); PointerKey retVal = pointerKeys.getPointerKeyForExceptionalReturnValue(target); IntSet set = getPointsToSet(retVal).getBackingSet(); diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PointerFlowGraph.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PointerFlowGraph.java index 672144717..62f388110 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PointerFlowGraph.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/PointerFlowGraph.java @@ -461,7 +461,7 @@ public class PointerFlowGraph extends AbstractGraph { @Override public void visitInvoke(SSAInvokeInstruction instruction) { - for (Iterator it = node.getPossibleTargets(instruction.getCallSite()).iterator(); it.hasNext();) { + for (Iterator it = cg.getPossibleTargets(node, instruction.getCallSite()).iterator(); it.hasNext();) { CGNode target = (CGNode) it.next(); // some methods, like unmodelled natives, do not have IR. 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 9746bd4d6..534f50ffe 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 @@ -1418,6 +1418,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap * if non-null, then this is the unique PointerKey that catches all * exceptions from this call site. */ + @SuppressWarnings("deprecation") private void processResolvedCall(CGNode caller, SSAAbstractInvokeInstruction instruction, CGNode target, InstanceKey[][] constParams, PointerKey uniqueCatchKey) { @@ -1660,7 +1661,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap Trace.println("Warning: null target for call " + call + " " + iKey); } } else { - IntSet targets = node.getPossibleTargetNumbers(call.getCallSite()); + IntSet targets = getCallGraph().getPossibleTargetNumbers(node,call.getCallSite()); if (targets != null && targets.contains(target.getGraphNodeId())) { // do nothing; we've previously discovered and handled this // receiver for this call site. @@ -1703,7 +1704,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap private boolean willNeverChangeAgain(IntSet receivers) { int bound = getBoundOnNumberOfTargets(node, call.getSite()); if (bound > -1) { - int nTargets = node.getNumberOfTargets(call.getSite()); + int nTargets = getCallGraph().getNumberOfTargets(node, call.getSite()); if (Assertions.verifyAssertions) { if (nTargets > bound) { Trace.println("node: " + node); @@ -1711,7 +1712,7 @@ public abstract class SSAPropagationCallGraphBuilder extends PropagationCallGrap Trace.println("instruction " + call); Trace.println("nTargets: " + nTargets); Trace.println("bound: " + bound); - for (Iterator it = node.getPossibleTargets(call.getSite()).iterator(); it.hasNext();) { + for (Iterator it = getCallGraph().getPossibleTargets(node, call.getSite()).iterator(); it.hasNext();) { Trace.println(" " + it.next()); } for (IntIterator intIt = receivers.intIterator(); intIt.hasNext();) { diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/rta/AbstractRTABuilder.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/rta/AbstractRTABuilder.java index dc492413a..6c54257fd 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/rta/AbstractRTABuilder.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/rta/AbstractRTABuilder.java @@ -323,6 +323,7 @@ public abstract class AbstractRTABuilder extends PropagationCallGraphBuilder { * * Side effect: add edge to the call graph. */ + @SuppressWarnings("deprecation") void processResolvedCall(CGNode caller, CallSiteReference site, CGNode target) { if (DEBUG) { diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/rta/BasicRTABuilder.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/rta/BasicRTABuilder.java index ae70c626b..25e11eb78 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/rta/BasicRTABuilder.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/rta/BasicRTABuilder.java @@ -188,7 +188,7 @@ public class BasicRTABuilder extends AbstractRTABuilder { } } - IntSet targets = caller.getPossibleTargetNumbers(site); + IntSet targets = getCallGraph().getPossibleTargetNumbers(caller,site); if (targets != null && targets.contains(target.getGraphNodeId())) { // do nothing; we've previously discovered and handled this // receiver for this call site. diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/rta/DelegatingExplicitCallGraph.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/rta/DelegatingExplicitCallGraph.java index 871d44994..d6dbd0147 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/rta/DelegatingExplicitCallGraph.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/callgraph/propagation/rta/DelegatingExplicitCallGraph.java @@ -79,7 +79,7 @@ public class DelegatingExplicitCallGraph extends ExplicitCallGraph { Object n = it.next(); if (n instanceof CallSite) { ExplicitNode delegate = (ExplicitNode) ((CallSite) n).getNode(); - IntSet s = delegate.getPossibleTargetNumbers(((CallSite) n).getSite()); + IntSet s = DelegatingExplicitCallGraph.this.getPossibleTargetNumbers(delegate, ((CallSite) n).getSite()); if (s != null) { result.addAll(s); } @@ -98,7 +98,7 @@ public class DelegatingExplicitCallGraph extends ExplicitCallGraph { CallSite p = (CallSite) result; CGNode n = p.getNode(); CallSiteReference s = p.getSite(); - return n.getPossibleTargets(s); + return DelegatingExplicitCallGraph.this.getPossibleTargets(n, s); } else { return super.getPossibleTargets(site); } @@ -125,7 +125,7 @@ public class DelegatingExplicitCallGraph extends ExplicitCallGraph { Object n = it.next(); if (n instanceof CallSite) { ExplicitNode delegate = (ExplicitNode) ((CallSite) n).getNode(); - IntSet s = delegate.getPossibleTargetNumbers(((CallSite) n).getSite()); + IntSet s = DelegatingExplicitCallGraph.this.getPossibleTargetNumbers(delegate,((CallSite) n).getSite()); if (s!= null && s.contains(y)) { return true; } @@ -142,7 +142,7 @@ public class DelegatingExplicitCallGraph extends ExplicitCallGraph { CallSite p = (CallSite) result; CGNode n = p.getNode(); CallSiteReference s = p.getSite(); - return n.getNumberOfTargets(s); + return DelegatingExplicitCallGraph.this.getNumberOfTargets(n,s); } else { return super.getNumberOfTargets(site); } diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/cfg/InterproceduralCFG.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/cfg/InterproceduralCFG.java index 281bb5267..e96e2ca23 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/cfg/InterproceduralCFG.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/cfg/InterproceduralCFG.java @@ -277,7 +277,7 @@ public class InterproceduralCFG implements NumberedGraph { Trace.println("got Site: " + site); } boolean irrelevantTargets = false; - for (Iterator ts = n.getPossibleTargets(site).iterator(); ts.hasNext();) { + for (Iterator ts = cg.getPossibleTargets(n, site).iterator(); ts.hasNext();) { CGNode tn = (CGNode) ts.next(); if (!relevant.accepts(tn)) { if (DEBUG_LEVEL > 0) { @@ -490,7 +490,7 @@ public class InterproceduralCFG implements NumberedGraph { IInvokeInstruction call = (IInvokeInstruction) cinsts[i]; CallSiteReference site = makeCallSiteReference(n.getMethod().getDeclaringClass().getClassLoader().getReference(), ccfg .getProgramCounter(i), call); - if (caller.getPossibleTargets(site).contains(n)) { + if (cg.getPossibleTargets(caller, site).contains(n)) { if (DEBUG_LEVEL > 0) { Trace.println("Adding edge " + ccfg.getBlockForInstruction(i) + " to " + bb); } @@ -701,7 +701,6 @@ public class InterproceduralCFG implements NumberedGraph { } /** - * @param B * @return the set of CGNodes that B may call, according to the governing call * graph. */ @@ -710,8 +709,8 @@ public class InterproceduralCFG implements NumberedGraph { IInvokeInstruction call = (IInvokeInstruction) statements[B.getLastInstructionIndex()]; int pc = cfg.getProgramCounter(B.getLastInstructionIndex()); CallSiteReference site = makeCallSiteReference(B.getMethod().getDeclaringClass().getClassLoader().getReference(), pc, call); - HashSet result = HashSetFactory.make(Bnode.getNumberOfTargets(site)); - for (Iterator it = Bnode.getPossibleTargets(site).iterator(); it.hasNext();) { + HashSet result = HashSetFactory.make(cg.getNumberOfTargets(Bnode,site)); + for (Iterator it = cg.getPossibleTargets(Bnode,site).iterator(); it.hasNext();) { CGNode target = it.next(); result.add(target); } diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/HeapReachingDefs.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/HeapReachingDefs.java index c798af696..4aea02e5e 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/HeapReachingDefs.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/HeapReachingDefs.java @@ -28,6 +28,7 @@ import com.ibm.wala.dataflow.graph.ITransferFunctionProvider; import com.ibm.wala.fixedpoint.impl.UnaryOperator; import com.ibm.wala.fixpoint.BitVectorVariable; import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.ipa.callgraph.CallGraph; import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis; import com.ibm.wala.ipa.callgraph.propagation.PointerKey; import com.ibm.wala.ipa.callgraph.propagation.StaticFieldKey; @@ -93,7 +94,7 @@ public class HeapReachingDefs { * if statements is null */ public static Map> computeReachingDefs(CGNode node, IR ir, PointerAnalysis pa, - Map> mod, Collection statements, HeapExclusions exclusions) { + Map> mod, Collection statements, HeapExclusions exclusions, CallGraph cg) { if (statements == null) { throw new IllegalArgumentException("statements is null"); @@ -129,21 +130,24 @@ public class HeapReachingDefs { System.err.println("Solved. "); } return makeResult(solver, domain, node, new DelegatingExtendedHeapModel(pa.getHeapModel()), pa, mod, cfg, - ssaInstructionIndex2Statement, exclusions); + ssaInstructionIndex2Statement, exclusions, cg); } private static class RDMap implements Map> { final Map> delegate = HashMapFactory.make(); private final HeapExclusions exclusions; + + private final CallGraph cg; RDMap(BitVectorSolver solver, OrdinalSetMapping domain, CGNode node, ExtendedHeapModel h, PointerAnalysis pa, Map> mod, ExpandedControlFlowGraph cfg, - Map ssaInstructionIndex2Statement, HeapExclusions exclusions) { + Map ssaInstructionIndex2Statement, HeapExclusions exclusions, CallGraph cg) { if (VERBOSE) { System.err.println("Init pointer Key mod "); } this.exclusions = exclusions; + this.cg = cg; Map pointerKeyMod = initPointerKeyMod(domain, node, h, pa); if (VERBOSE) { System.err.println("Eager populate"); @@ -313,7 +317,7 @@ public class HeapReachingDefs { HeapStatement.ReturnCaller r = (HeapStatement.ReturnCaller) s; IBasicBlock bb = cfg.getBlockForInstruction(r.getCall()); BitVectorVariable v = (BitVectorVariable) solver.getIn(bb); - if (allCalleesMod(r, mod) || pointerKeyMod.get(r.getLocation()) == null || v.getValue() == null) { + if (allCalleesMod(cg, r, mod) || pointerKeyMod.get(r.getLocation()) == null || v.getValue() == null) { // do nothing ... force flow into and out of the callees return OrdinalSet.empty(); } else { @@ -364,19 +368,17 @@ public class HeapReachingDefs { private static Map> makeResult(BitVectorSolver solver, OrdinalSetMapping domain, CGNode node, ExtendedHeapModel h, PointerAnalysis pa, Map> mod, ExpandedControlFlowGraph cfg, - Map ssaInstructionIndex2Statement, HeapExclusions exclusions) { + Map ssaInstructionIndex2Statement, HeapExclusions exclusions, CallGraph cg) { - return new RDMap(solver, domain, node, h, pa, mod, cfg, ssaInstructionIndex2Statement, exclusions); + return new RDMap(solver, domain, node, h, pa, mod, cfg, ssaInstructionIndex2Statement, exclusions, cg); } /** * Do all callees corresponding to the given call site def the pointer key * being tracked by r? - * - * @param mod */ - private static boolean allCalleesMod(ReturnCaller r, Map> mod) { - Collection targets = r.getNode().getPossibleTargets(r.getCall().getCallSite()); + private static boolean allCalleesMod(CallGraph cg, ReturnCaller r, Map> mod) { + Collection targets = cg.getPossibleTargets(r.getNode(), r.getCall().getCallSite()); if (targets.isEmpty()) { return false; } diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/PDG.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/PDG.java index 2301a6047..6a2d90313 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/PDG.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/PDG.java @@ -21,6 +21,7 @@ import com.ibm.wala.cfg.cdg.ControlDependenceGraph; import com.ibm.wala.classLoader.CallSiteReference; import com.ibm.wala.classLoader.IClass; import com.ibm.wala.ipa.callgraph.CGNode; +import com.ibm.wala.ipa.callgraph.CallGraph; import com.ibm.wala.ipa.callgraph.impl.SetOfClasses; import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis; import com.ibm.wala.ipa.callgraph.propagation.PointerKey; @@ -96,6 +97,8 @@ public class PDG extends SlowSparseNumberedGraph { private final Map> mod; private final DataDependenceOptions dOptions; + + private final CallGraph cg; /** * @param mod @@ -109,12 +112,13 @@ public class PDG extends SlowSparseNumberedGraph { */ public PDG(final CGNode node, PointerAnalysis pa, Map> mod, Map> ref, DataDependenceOptions dOptions, ControlDependenceOptions cOptions, - HeapExclusions exclusions) { + HeapExclusions exclusions, CallGraph cg) { super(); if (node == null) { throw new IllegalArgumentException("node is null"); } + this.cg = cg; this.node = node; this.heapModel = pa == null ? null : new DelegatingExtendedHeapModel(pa.getHeapModel()); this.pa = pa; @@ -493,7 +497,7 @@ public class PDG extends SlowSparseNumberedGraph { Collection relevantStatements = Iterator2Collection.toCollection(new FilterIterator(iterator(), f)); Map> heapReachingDefs = dOptions.isIgnoreHeap() ? null : HeapReachingDefs.computeReachingDefs( - node, ir, pa, mod, relevantStatements, new HeapExclusions(SetComplement.complement(new SingletonSet(t)))); + node, ir, pa, mod, relevantStatements, new HeapExclusions(SetComplement.complement(new SingletonSet(t))), cg); for (Statement st : heapReachingDefs.keySet()) { switch (st.getKind()) { @@ -829,13 +833,13 @@ public class PDG extends SlowSparseNumberedGraph { } if (!dOptions.isIgnoreHeap()) { - OrdinalSet uref = unionHeapLocations(node, call, ref); + OrdinalSet uref = unionHeapLocations(cg, node, call, ref); for (PointerKey p : uref) { Statement st = new HeapStatement.ParamCaller(node, callIndex, p); addNode(st); params.add(st); } - OrdinalSet umod = unionHeapLocations(node, call, mod); + OrdinalSet umod = unionHeapLocations(cg, node, call, mod); for (PointerKey p : umod) { Statement st = new HeapStatement.ReturnCaller(node, callIndex, p); addNode(st); @@ -847,10 +851,10 @@ public class PDG extends SlowSparseNumberedGraph { /** * @return the set of all locations read by any callee at a call site. */ - private OrdinalSet unionHeapLocations(CGNode n, SSAAbstractInvokeInstruction call, + private OrdinalSet unionHeapLocations(CallGraph cg, CGNode n, SSAAbstractInvokeInstruction call, Map> loc) { BitVectorIntSet bv = new BitVectorIntSet(); - for (CGNode t : n.getPossibleTargets(call.getCallSite())) { + for (CGNode t : cg.getPossibleTargets(n, call.getCallSite())) { bv.addAll(loc.get(t).getBackingSet()); } return new OrdinalSet(bv, loc.get(n).getMapping()); diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/SDG.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/SDG.java index 2ab1c1b9a..95d278667 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/SDG.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/SDG.java @@ -212,7 +212,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { Collection result = Iterator2Collection.toCollection(getPDG(N.getNode()).getPredNodes(N)); if (!dOptions.equals(DataDependenceOptions.NONE)) { // data dependence predecessors - for (CGNode t : N.getNode().getPossibleTargets(call.getCallSite())) { + for (CGNode t : cg.getPossibleTargets(N.getNode(),call.getCallSite())) { Statement s = new ParamStatement.ExceptionalReturnCallee(t); addNode(s); result.add(s); @@ -226,7 +226,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { Collection result = Iterator2Collection.toCollection(getPDG(N.getNode()).getPredNodes(N)); if (!dOptions.equals(DataDependenceOptions.NONE)) { // data dependence predecessors - for (CGNode t : N.getNode().getPossibleTargets(call.getCallSite())) { + for (CGNode t : cg.getPossibleTargets(N.getNode(), call.getCallSite())) { Statement s = new ParamStatement.NormalReturnCallee(t); addNode(s); result.add(s); @@ -240,7 +240,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { Collection result = Iterator2Collection.toCollection(getPDG(N.getNode()).getPredNodes(N)); if (!dOptions.equals(DataDependenceOptions.NONE)) { // data dependence predecessors - for (CGNode t : N.getNode().getPossibleTargets(call.getCallSite())) { + for (CGNode t : cg.getPossibleTargets(N.getNode(), call.getCallSite())) { if (mod.get(t).contains(r.getLocation())) { Statement s = new HeapStatement.ReturnCallee(t, r.getLocation()); addNode(s); @@ -258,7 +258,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { // data dependence predecessors for (Iterator it = cg.getPredNodes(N.getNode()); it.hasNext();) { CGNode caller = it.next(); - for (Iterator it2 = caller.getPossibleSites(N.getNode()); it2.hasNext();) { + for (Iterator it2 = cg.getPossibleSites(caller, N.getNode()); it2.hasNext();) { CallSiteReference site = it2.next(); IR ir = caller.getIR(); IntSet indices = ir.getCallInstructionIndices(site); @@ -287,7 +287,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { // data dependence predecessors for (Iterator it = cg.getPredNodes(N.getNode()); it.hasNext();) { CGNode caller = it.next(); - for (Iterator it2 = caller.getPossibleSites(N.getNode()); it2.hasNext();) { + for (Iterator it2 = cg.getPossibleSites(caller, N.getNode()); it2.hasNext();) { CallSiteReference site = it2.next(); IR ir = caller.getIR(); IntSet indices = ir.getCallInstructionIndices(site); @@ -312,7 +312,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { if (!cOptions.equals(ControlDependenceOptions.NONE)) { for (Iterator it = cg.getPredNodes(N.getNode()); it.hasNext();) { CGNode caller = it.next(); - for (Iterator it2 = caller.getPossibleSites(N.getNode()); it2.hasNext();) { + for (Iterator it2 = cg.getPossibleSites(caller, N.getNode()); it2.hasNext();) { CallSiteReference site = it2.next(); IR ir = caller.getIR(); IntSet indices = ir.getCallInstructionIndices(site); @@ -346,7 +346,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { if (ns.getInstruction() instanceof SSAAbstractInvokeInstruction) { HashSet result = HashSetFactory.make(); SSAAbstractInvokeInstruction call = (SSAAbstractInvokeInstruction) ns.getInstruction(); - for (CGNode t : N.getNode().getPossibleTargets(call.getCallSite())) { + for (CGNode t : cg.getPossibleTargets(N.getNode(), call.getCallSite())) { Statement s = new MethodEntryStatement(t); addNode(s); result.add(s); @@ -371,7 +371,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { // data dependence predecessors for (Iterator it = cg.getPredNodes(N.getNode()); it.hasNext();) { CGNode caller = it.next(); - for (Iterator it2 = caller.getPossibleSites(N.getNode()); it2.hasNext();) { + for (Iterator it2 = cg.getPossibleSites(caller, N.getNode()); it2.hasNext();) { CallSiteReference site = it2.next(); IR ir = caller.getIR(); IntSet indices = ir.getCallInstructionIndices(site); @@ -393,7 +393,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { // data dependence predecessors for (Iterator it = cg.getPredNodes(N.getNode()); it.hasNext();) { CGNode caller = it.next(); - for (Iterator it2 = caller.getPossibleSites(N.getNode()); it2.hasNext();) { + for (Iterator it2 = cg.getPossibleSites(caller, N.getNode()); it2.hasNext();) { CallSiteReference site = it2.next(); IR ir = caller.getIR(); IntSet indices = ir.getCallInstructionIndices(site); @@ -416,7 +416,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { // data dependence predecessors for (Iterator it = cg.getPredNodes(N.getNode()); it.hasNext();) { CGNode caller = it.next(); - for (Iterator it2 = caller.getPossibleSites(N.getNode()); it2.hasNext();) { + for (Iterator it2 = cg.getPossibleSites(caller, N.getNode()); it2.hasNext();) { CallSiteReference site = it2.next(); IR ir = caller.getIR(); IntSet indices = ir.getCallInstructionIndices(site); @@ -437,7 +437,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { Collection result = HashSetFactory.make(5); if (!dOptions.equals(DataDependenceOptions.NONE)) { // data dependence successors - for (CGNode t : N.getNode().getPossibleTargets(call.getCallSite())) { + for (CGNode t : cg.getPossibleTargets(N.getNode(), call.getCallSite())) { for (int i = 0; i < t.getMethod().getNumberOfParameters(); i++) { if (call.getUse(i) == pac.getValueNumber()) { Statement s = new ParamStatement.ParamCallee(t, i + 1); @@ -455,7 +455,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { Collection result = HashSetFactory.make(5); if (!dOptions.equals(DataDependenceOptions.NONE)) { // data dependence successors - for (CGNode t : N.getNode().getPossibleTargets(call.getCallSite())) { + for (CGNode t : cg.getPossibleTargets(N.getNode(), call.getCallSite())) { if (ref.get(t).contains(pc.getLocation())) { Statement s = new HeapStatement.ParamCallee(t, pc.getLocation()); addNode(s); @@ -480,7 +480,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { if (dst instanceof MethodEntryStatement) { if (ns.getInstruction() instanceof SSAAbstractInvokeInstruction) { SSAAbstractInvokeInstruction call = (SSAAbstractInvokeInstruction) ns.getInstruction(); - return src.getNode().getPossibleTargets(call.getCallSite()).contains(dst.getNode()); + return cg.getPossibleTargets(src.getNode(), call.getCallSite()).contains(dst.getNode()); } else { return false; } @@ -502,7 +502,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { } if (dst.getKind().equals(Kind.EXC_RET_CALLER)) { ParamStatement.ExceptionalReturnCaller r = (ParamStatement.ExceptionalReturnCaller) dst; - return r.getNode().getPossibleTargets(r.getCall().getCallSite()).contains(src.getNode()); + return cg.getPossibleTargets(r.getNode(), r.getCall().getCallSite()).contains(src.getNode()); } else { return false; } @@ -513,7 +513,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { } if (dst.getKind().equals(Kind.NORMAL_RET_CALLER)) { ParamStatement.NormalReturnCaller r = (ParamStatement.NormalReturnCaller) dst; - return r.getNode().getPossibleTargets(r.getCall().getCallSite()).contains(src.getNode()); + return cg.getPossibleTargets(r.getNode(), r.getCall().getCallSite()).contains(src.getNode()); } else { return false; } @@ -526,7 +526,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { HeapStatement.ReturnCaller r = (HeapStatement.ReturnCaller) dst; HeapStatement h = (HeapStatement) src; return h.getLocation().equals(r.getLocation()) - && r.getNode().getPossibleTargets(r.getCall().getCallSite()).contains(src.getNode()); + && cg.getPossibleTargets(r.getNode(), r.getCall().getCallSite()).contains(src.getNode()); } else { return false; } @@ -540,7 +540,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { ParamStatement.ParamCaller caller = (ParamStatement.ParamCaller) src; return caller.getValueNumber() == callee.getValueNumber() - && caller.getNode().getPossibleTargets(caller.getCall().getCallSite()).contains(callee.getNode()); + && cg.getPossibleTargets(caller.getNode(), caller.getCall().getCallSite()).contains(callee.getNode()); } else { return false; } @@ -554,7 +554,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { HeapStatement.ParamCaller caller = (HeapStatement.ParamCaller) src; return caller.getLocation().equals(callee.getLocation()) - && caller.getNode().getPossibleTargets(caller.getCall().getCallSite()).contains(callee.getNode()); + && cg.getPossibleTargets(caller.getNode(), caller.getCall().getCallSite()).contains(callee.getNode()); } else { return false; } @@ -618,7 +618,7 @@ public class SDG extends AbstractNumberedGraph implements ISDG { public PDG getPDG(CGNode node) { PDG result = pdgMap.get(node); if (result == null) { - result = new PDG(node, pa, mod, ref, dOptions, cOptions, heapExclude); + result = new PDG(node, pa, mod, ref, dOptions, cOptions, heapExclude, cg); pdgMap.put(node, result); for (Iterator it = result.iterator(); it.hasNext();) { nodeMgr.addNode(it.next()); @@ -631,4 +631,8 @@ public class SDG extends AbstractNumberedGraph implements ISDG { return cOptions; } + public CallGraph getCallGraph() { + return cg; + } + }