use of soot.util.queue.ChunkedQueue in project soot by Sable.
the class GeomPointsTo method updateCallGraph.
/**
* Remove unreachable call targets at the virtual callsites using the up-to-date points-to information.
*/
private int updateCallGraph() {
int all_virtual_edges = 0, n_obsoleted = 0;
CallGraph cg = Scene.v().getCallGraph();
ChunkedQueue<SootMethod> targetsQueue = new ChunkedQueue<SootMethod>();
QueueReader<SootMethod> targets = targetsQueue.reader();
Set<SootMethod> resolvedMethods = new HashSet<SootMethod>();
// We first update the virtual callsites
for (Iterator<Stmt> csIt = multiCallsites.iterator(); csIt.hasNext(); ) {
Stmt callsite = csIt.next();
Iterator<Edge> edges = cg.edgesOutOf(callsite);
if (!edges.hasNext()) {
csIt.remove();
continue;
}
Edge anyEdge = edges.next();
CgEdge p = edgeMapping.get(anyEdge);
SootMethod src = anyEdge.src();
if (!isReachableMethod(src)) {
// The source method is no longer reachable
// We move this callsite
csIt.remove();
continue;
}
if (!edges.hasNext()) {
// We keep this resolved site for call graph profiling
continue;
}
IVarAbstraction pn = consG.get(p.base_var);
if (pn != null) {
pn = pn.getRepresentative();
// We resolve the call targets with the new points-to result
getCallTargets(pn, src, callsite, targetsQueue);
resolvedMethods.clear();
while (targets.hasNext()) {
resolvedMethods.add(targets.next());
}
// We delete the edges that are proven to be spurious
while (true) {
SootMethod tgt = anyEdge.tgt();
if (!resolvedMethods.contains(tgt) && !anyEdge.kind().isFake()) {
p = edgeMapping.get(anyEdge);
p.is_obsoleted = true;
}
if (!edges.hasNext())
break;
anyEdge = edges.next();
}
}
}
// We delete the spurious edges
for (int i = 1; i < n_func; ++i) {
// New outgoing edge list is pointed to by q
CgEdge p = call_graph[i];
CgEdge q = null;
while (p != null) {
if (vis_cg[i] == 0) {
// If this method is unreachable, we delete all its outgoing edges
p.is_obsoleted = true;
}
if (p.base_var != null) {
++all_virtual_edges;
}
CgEdge temp = p.next;
if (p.is_obsoleted == false) {
p.next = q;
q = p;
} else {
// Update the corresponding SOOT call graph
// ps.println("%%% Remove an call edge: " + p.toString());
cg.removeEdge(p.sootEdge);
// We record this obsoleted edge
// obsoletedEdges.add(p);
++n_obsoleted;
}
p = temp;
}
call_graph[i] = q;
}
ps.printf("%d of %d virtual call edges are proved to be spurious.\n", n_obsoleted, all_virtual_edges);
return n_obsoleted;
}
use of soot.util.queue.ChunkedQueue in project soot by Sable.
the class SootUtil method getCallTargets.
public static Collection<? extends SootMethod> getCallTargets(Type type, SootMethod invokedMethod) {
if (isConstructor(invokedMethod)) {
return Collections.singleton(invokedMethod);
}
Type receiverType = invokedMethod.getDeclaringClass().getType();
ChunkedQueue chunkedQueue = new ChunkedQueue();
Iterator iter = chunkedQueue.reader();
VirtualCalls.v().resolve(type, receiverType, invokedMethod.getNumberedSubSignature(), null, chunkedQueue);
Set<SootMethod> ret = new ArraySet<SootMethod>();
for (; iter.hasNext(); ) {
SootMethod target = (SootMethod) iter.next();
ret.add(target);
}
return ret;
}
Aggregations