diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/modref/ModRef.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/modref/ModRef.java index c77c62ea5..91301ebfd 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/modref/ModRef.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/modref/ModRef.java @@ -57,7 +57,7 @@ public class ModRef { * @throws IllegalArgumentException if cg is null * */ - public static Map> computeMod(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) { + public Map> computeMod(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) { if (cg == null) { throw new IllegalArgumentException("cg is null"); } @@ -71,7 +71,7 @@ public class ModRef { * @throws IllegalArgumentException if cg is null * */ - public static Map> computeRef(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) { + public Map> computeRef(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) { if (cg == null) { throw new IllegalArgumentException("cg is null"); } @@ -84,7 +84,7 @@ public class ModRef { * model) may it write, including its callees transitively * */ - public static Map> computeMod(CallGraph cg, PointerAnalysis pa) { + public Map> computeMod(CallGraph cg, PointerAnalysis pa) { return computeMod(cg, pa, null); } @@ -93,11 +93,11 @@ public class ModRef { * model) may it read, including its callees transitively * */ - public static Map> computeRef(CallGraph cg, PointerAnalysis pa) { + public Map> computeRef(CallGraph cg, PointerAnalysis pa) { return computeRef(cg, pa, null); } - private static Map> transitiveClosure(CallGraph cg, Map> scan) { + private Map> transitiveClosure(CallGraph cg, Map> scan) { GenReach gr = new GenReach(GraphInverter.invert(cg), scan); BitVectorSolver solver = new BitVectorSolver(gr); solver.solve(); @@ -116,7 +116,7 @@ public class ModRef { * * @param heapExclude */ - private static Map> scanForMod(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) { + private Map> scanForMod(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) { Map> result = HashMapFactory.make(); for (Iterator it = cg.iterator(); it.hasNext();) { CGNode n = it.next(); @@ -131,7 +131,7 @@ public class ModRef { * * @param heapExclude */ - private static Map> scanForRef(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) { + private Map> scanForRef(CallGraph cg, PointerAnalysis pa, HeapExclusions heapExclude) { Map> result = HashMapFactory.make(); for (Iterator it = cg.iterator(); it.hasNext();) { CGNode n = it.next(); @@ -146,10 +146,10 @@ public class ModRef { * * @param heapExclude */ - private static Collection scanNodeForMod(final CGNode n, final PointerAnalysis pa, HeapExclusions heapExclude) { + private Collection scanNodeForMod(final CGNode n, final PointerAnalysis pa, HeapExclusions heapExclude) { Collection result = HashSetFactory.make(); final ExtendedHeapModel h = new DelegatingExtendedHeapModel(pa.getHeapModel()); - SSAInstruction.Visitor v = new ModVisitor(n, result, h, pa); + SSAInstruction.Visitor v = makeModVisitor(n, result, pa, h); IR ir = n.getIR(); if (ir != null) { for (Iterator it = ir.iterateNormalInstructions(); it.hasNext();) { @@ -166,10 +166,10 @@ public class ModRef { * For a call graph node, what heap locations (as determined by a heap model) * may it read, NOT including it's callees transitively */ - private static Collection scanNodeForRef(final CGNode n, final PointerAnalysis pa, HeapExclusions heapExclude) { + private Collection scanNodeForRef(final CGNode n, final PointerAnalysis pa, HeapExclusions heapExclude) { Collection result = HashSetFactory.make(); final ExtendedHeapModel h = new DelegatingExtendedHeapModel(pa.getHeapModel()); - SSAInstruction.Visitor v = new RefVisitor(n, result, pa, h); + SSAInstruction.Visitor v = makeRefVisitor(n, result, pa, h); IR ir = n.getIR(); if (ir != null) { for (Iterator it = ir.iterateNormalInstructions(); it.hasNext();) { @@ -182,7 +182,7 @@ public class ModRef { return result; } - private static final class RefVisitor extends SSAInstruction.Visitor { + protected static class RefVisitor extends SSAInstruction.Visitor { private final CGNode n; private final Collection result; @@ -191,7 +191,7 @@ public class ModRef { private final ExtendedHeapModel h; - private RefVisitor(CGNode n, Collection result, PointerAnalysis pa, ExtendedHeapModel h) { + protected RefVisitor(CGNode n, Collection result, PointerAnalysis pa, ExtendedHeapModel h) { this.n = n; this.result = result; this.pa = pa; @@ -230,7 +230,7 @@ public class ModRef { } } - private static final class ModVisitor extends SSAInstruction.Visitor { + protected static class ModVisitor extends SSAInstruction.Visitor { private final CGNode n; private final Collection result; @@ -239,7 +239,8 @@ public class ModRef { private final PointerAnalysis pa; - private ModVisitor(CGNode n, Collection result, ExtendedHeapModel h, PointerAnalysis pa) { + + protected ModVisitor(CGNode n, Collection result, ExtendedHeapModel h, PointerAnalysis pa) { this.n = n; this.result = result; this.h = h; @@ -324,24 +325,32 @@ public class ModRef { } } - public static Collection getMod(CGNode n, ExtendedHeapModel h, PointerAnalysis pa, SSAInstruction s, + protected ModVisitor makeModVisitor(CGNode n, Collection result, PointerAnalysis pa, ExtendedHeapModel h) { + return new ModVisitor(n, result, h, pa); + } + + public Collection getMod(CGNode n, ExtendedHeapModel h, PointerAnalysis pa, SSAInstruction s, HeapExclusions hexcl) { if (s == null) { throw new IllegalArgumentException("s is null"); } Collection result = HashSetFactory.make(2); - ModVisitor v = new ModVisitor(n, result, h, pa); + ModVisitor v = makeModVisitor(n, result, pa, h); s.visit(v); return hexcl == null ? result : hexcl.filter(result); } - public static Collection getRef(CGNode n, ExtendedHeapModel h, PointerAnalysis pa, SSAInstruction s, + protected RefVisitor makeRefVisitor(CGNode n, Collection result, PointerAnalysis pa, ExtendedHeapModel h) { + return new RefVisitor(n, result, pa, h); + } + + public Collection getRef(CGNode n, ExtendedHeapModel h, PointerAnalysis pa, SSAInstruction s, HeapExclusions hexcl) { if (s == null) { throw new IllegalArgumentException("s is null"); } Collection result = HashSetFactory.make(2); - RefVisitor v = new RefVisitor(n, result, pa, h); + RefVisitor v = makeRefVisitor(n, result, pa, h); s.visit(v); return hexcl == null ? result : hexcl.filter(result); } 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 3bb0f0ad5..ef119d6f2 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 @@ -69,6 +69,12 @@ public class HeapReachingDefs { private static final boolean VERBOSE = false; + private final ModRef modRef; + + public HeapReachingDefs(ModRef modRef) { + this.modRef = modRef; + } + /** * For each statement s, return the set of statements that may def the heap * value read by s. @@ -93,7 +99,7 @@ public class HeapReachingDefs { * @throws IllegalArgumentException * if statements is null */ - public static Map> computeReachingDefs(CGNode node, IR ir, PointerAnalysis pa, + public Map> computeReachingDefs(CGNode node, IR ir, PointerAnalysis pa, Map> mod, Collection statements, HeapExclusions exclusions, CallGraph cg) { if (statements == null) { @@ -132,7 +138,7 @@ public class HeapReachingDefs { ssaInstructionIndex2Statement, exclusions, cg); } - private static class RDMap implements Map> { + private class RDMap implements Map> { final Map> delegate = HashMapFactory.make(); private final HeapExclusions exclusions; @@ -194,7 +200,7 @@ public class HeapReachingDefs { return pointerKeyMod; } - private static MutableIntSet findOrCreateIntSet(Map map, PointerKey key) { + private MutableIntSet findOrCreateIntSet(Map map, PointerKey key) { MutableIntSet result = map.get(key); if (result == null) { result = new MutableSparseIntSet(); @@ -277,14 +283,14 @@ public class HeapReachingDefs { * For a statement s, compute the set of statements that may def the heap * value read by s. */ - private OrdinalSet computeResult(Statement s, Map pointerKeyMod, + OrdinalSet computeResult(Statement s, Map pointerKeyMod, BitVectorSolver solver, OrdinalSetMapping domain, CGNode node, ExtendedHeapModel h, PointerAnalysis pa, Map> mod, ExplodedControlFlowGraph cfg, Map ssaInstructionIndex2Statement) { switch (s.getKind()) { case NORMAL: NormalStatement n = (NormalStatement) s; - Collection ref = ModRef.getRef(node, h, pa, n.getInstruction(), exclusions); + Collection ref = modRef.getRef(node, h, pa, n.getInstruction(), exclusions); if (!ref.isEmpty()) { IBasicBlock bb = cfg.getBlockForInstruction(n.getInstructionIndex()); BitVectorVariable v = (BitVectorVariable) solver.getIn(bb); @@ -359,7 +365,7 @@ public class HeapReachingDefs { * For each statement s, compute the set of statements that may def the heap * value read by s. */ - private static Map> makeResult(BitVectorSolver solver, + private Map> makeResult(BitVectorSolver solver, OrdinalSetMapping domain, CGNode node, ExtendedHeapModel h, PointerAnalysis pa, Map> mod, ExplodedControlFlowGraph cfg, Map ssaInstructionIndex2Statement, HeapExclusions exclusions, CallGraph cg) { @@ -384,12 +390,12 @@ public class HeapReachingDefs { return true; } - private static Collection getMod(Statement s, CGNode n, ExtendedHeapModel h, PointerAnalysis pa, + private Collection getMod(Statement s, CGNode n, ExtendedHeapModel h, PointerAnalysis pa, HeapExclusions exclusions) { switch (s.getKind()) { case NORMAL: NormalStatement ns = (NormalStatement) s; - return ModRef.getMod(n, h, pa, ns.getInstruction(), exclusions); + return modRef.getMod(n, h, pa, ns.getInstruction(), exclusions); case HEAP_PARAM_CALLEE: case HEAP_RET_CALLER: HeapStatement hs = (HeapStatement) s; @@ -437,7 +443,7 @@ public class HeapReachingDefs { /** * Reaching def flow functions */ - private static class RD implements ITransferFunctionProvider { + private class RD implements ITransferFunctionProvider { private final CGNode node; @@ -552,7 +558,7 @@ public class HeapReachingDefs { assert (domainIndex != -1); return heapReturnCaller.getRelated(domainIndex); } else { - Collection gen = ModRef.getMod(node, h, pa, s, exclusions); + Collection gen = modRef.getMod(node, h, pa, s, exclusions); if (gen.isEmpty()) { return null; } else { @@ -587,7 +593,7 @@ public class HeapReachingDefs { if (s == null) { return null; } else { - Collection mod = ModRef.getMod(node, h, pa, s, exclusions); + Collection mod = modRef.getMod(node, h, pa, s, exclusions); if (mod.isEmpty()) { return null; } else { 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 5a3f1499b..bd069b30d 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 @@ -102,6 +102,8 @@ public class PDG extends SlowSparseNumberedGraph { private final CallGraph cg; + private final ModRef modRef; + /** * @param mod * the set of heap locations which may be written (transitively) by @@ -114,7 +116,7 @@ public class PDG extends SlowSparseNumberedGraph { */ public PDG(final CGNode node, PointerAnalysis pa, Map> mod, Map> ref, DataDependenceOptions dOptions, ControlDependenceOptions cOptions, - HeapExclusions exclusions, CallGraph cg) { + HeapExclusions exclusions, CallGraph cg, ModRef modRef) { super(); if (node == null) { @@ -127,6 +129,7 @@ public class PDG extends SlowSparseNumberedGraph { this.dOptions = dOptions; this.mod = mod; this.exclusions = exclusions; + this.modRef = modRef; instructionIndices = computeInstructionIndices(node.getIR()); createNodes(ref, cOptions); createScalarEdges(cOptions); @@ -511,7 +514,7 @@ public class PDG extends SlowSparseNumberedGraph { }; Collection relevantStatements = Iterator2Collection.toCollection(new FilterIterator(iterator(), f)); - Map> heapReachingDefs = dOptions.isIgnoreHeap() ? null : HeapReachingDefs.computeReachingDefs( + Map> heapReachingDefs = dOptions.isIgnoreHeap() ? null : (new HeapReachingDefs(modRef)).computeReachingDefs( node, ir, pa, mod, relevantStatements, new HeapExclusions(SetComplement.complement(new SingletonSet(t))), cg); for (Statement st : heapReachingDefs.keySet()) { @@ -930,7 +933,7 @@ public class PDG extends SlowSparseNumberedGraph { case NORMAL: NormalStatement st = (NormalStatement) N; if (!(IGNORE_ALLOC_HEAP_DEFS && st.getInstruction() instanceof SSANewInstruction)) { - Collection ref = ModRef.getRef(node, heapModel, pa, st.getInstruction(), exclusions); + Collection ref = modRef.getRef(node, heapModel, pa, st.getInstruction(), exclusions); for (PointerKey pk : ref) { createHeapDataDependenceEdges(pk); } @@ -950,7 +953,7 @@ public class PDG extends SlowSparseNumberedGraph { case NORMAL: NormalStatement st = (NormalStatement) N; if (!(IGNORE_ALLOC_HEAP_DEFS && st.getInstruction() instanceof SSANewInstruction)) { - Collection ref = ModRef.getMod(node, heapModel, pa, st.getInstruction(), exclusions); + Collection ref = modRef.getMod(node, heapModel, pa, st.getInstruction(), exclusions); for (PointerKey pk : ref) { createHeapDataDependenceEdges(pk); } 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 95d278667..dcf10b5ac 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 @@ -106,20 +106,26 @@ public class SDG extends AbstractNumberedGraph implements ISDG { */ private final HeapExclusions heapExclude; + private final ModRef modRef; public SDG(final CallGraph cg, PointerAnalysis pa, DataDependenceOptions dOptions, ControlDependenceOptions cOptions) { - this(cg, pa, dOptions, cOptions, null); + this(cg, pa, new ModRef(), dOptions, cOptions, null); } - public SDG(CallGraph cg, PointerAnalysis pa, DataDependenceOptions dOptions, ControlDependenceOptions cOptions, HeapExclusions heapExclude) throws IllegalArgumentException { + public SDG(final CallGraph cg, PointerAnalysis pa, ModRef modRef, DataDependenceOptions dOptions, ControlDependenceOptions cOptions) { + this(cg, pa, modRef, dOptions, cOptions, null); + } + + public SDG(CallGraph cg, PointerAnalysis pa, ModRef modRef, DataDependenceOptions dOptions, ControlDependenceOptions cOptions, HeapExclusions heapExclude) throws IllegalArgumentException { super(); if (dOptions == null) { throw new IllegalArgumentException("dOptions must not be null"); } + this.modRef = modRef; this.cg = cg; this.pa = pa; - this.mod = dOptions.isIgnoreHeap() ? null : ModRef.computeMod(cg, pa, heapExclude); - this.ref = dOptions.isIgnoreHeap() ? null : ModRef.computeRef(cg, pa, heapExclude); + this.mod = dOptions.isIgnoreHeap() ? null : modRef.computeMod(cg, pa, heapExclude); + this.ref = dOptions.isIgnoreHeap() ? null : modRef.computeRef(cg, pa, heapExclude); this.dOptions = dOptions; this.cOptions = cOptions; this.heapExclude = heapExclude; @@ -618,7 +624,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, cg); + result = new PDG(node, pa, mod, ref, dOptions, cOptions, heapExclude, cg, modRef); pdgMap.put(node, result); for (Iterator it = result.iterator(); it.hasNext();) { nodeMgr.addNode(it.next()); diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/Slicer.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/Slicer.java index 06e259d94..0acf5091a 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/Slicer.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/Slicer.java @@ -25,6 +25,7 @@ import com.ibm.wala.dataflow.IFDS.TabulationResult; import com.ibm.wala.dataflow.IFDS.TabulationSolver; import com.ibm.wala.ipa.callgraph.CallGraph; import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis; +import com.ibm.wala.ipa.modref.ModRef; import com.ibm.wala.ipa.slicer.Statement.Kind; import com.ibm.wala.util.collections.HashSetFactory; import com.ibm.wala.util.collections.Iterator2Collection; @@ -190,7 +191,12 @@ public class Slicer { * @param ss * a collection of statements of interest */ - private static Collection computeSlice(SDG sdg, Collection ss, CallGraph cg, PointerAnalysis pa, + protected static Collection computeSlice(SDG sdg, Collection ss, CallGraph cg, PointerAnalysis pa, + DataDependenceOptions dOptions, ControlDependenceOptions cOptions, boolean backward) { + return computeSlice(sdg, ss, cg, pa, new ModRef(), dOptions, cOptions, backward); + } + + protected static Collection computeSlice(SDG sdg, Collection ss, CallGraph cg, PointerAnalysis pa, ModRef modRef, DataDependenceOptions dOptions, ControlDependenceOptions cOptions, boolean backward) { if (VERBOSE) { @@ -198,7 +204,7 @@ public class Slicer { } if (sdg == null) { - sdg = new SDG(cg, pa, dOptions, cOptions); + sdg = new SDG(cg, pa, modRef, dOptions, cOptions); } Collection rootsConsidered = HashSetFactory.make(); diff --git a/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/thin/ThinSlicer.java b/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/thin/ThinSlicer.java index be5957f95..a31a21d42 100644 --- a/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/thin/ThinSlicer.java +++ b/com.ibm.wala.core/src/com/ibm/wala/ipa/slicer/thin/ThinSlicer.java @@ -61,7 +61,11 @@ public class ThinSlicer { private final Graph depGraph; public ThinSlicer(CallGraph cg, PointerAnalysis pa) { - SDG sdg = new SDG(cg, pa, DataDependenceOptions.NO_BASE_NO_HEAP, ControlDependenceOptions.NONE, null); + this(cg, pa, new ModRef()); + } + + public ThinSlicer(CallGraph cg, PointerAnalysis pa, ModRef modRef) { + SDG sdg = new SDG(cg, pa, modRef, DataDependenceOptions.NO_BASE_NO_HEAP, ControlDependenceOptions.NONE, null); Map> mod = scanForMod(sdg, pa); Map> ref = scanForRef(sdg, pa); @@ -270,7 +274,7 @@ public class ThinSlicer { Statement st = it.next(); switch (st.getKind()) { case NORMAL: - Set c = HashSetFactory.make(ModRef.getMod(st.getNode(), h, pa, ((NormalStatement) st).getInstruction(), + Set c = HashSetFactory.make((new ModRef()).getMod(st.getNode(), h, pa, ((NormalStatement) st).getInstruction(), null)); result.put(st, c); break; @@ -290,7 +294,7 @@ public class ThinSlicer { Statement st = it.next(); switch (st.getKind()) { case NORMAL: - Set c = HashSetFactory.make(ModRef.getRef(st.getNode(), h, pa, ((NormalStatement) st).getInstruction(), + Set c = HashSetFactory.make((new ModRef()).getRef(st.getNode(), h, pa, ((NormalStatement) st).getInstruction(), null)); result.put(st, c); break;