boomerang.results.BackwardBoomerangResults Maven / Gradle / Ivy
package boomerang.results;
import boomerang.BackwardQuery;
import boomerang.ForwardQuery;
import boomerang.Query;
import boomerang.Util;
import boomerang.scene.ControlFlowGraph.Edge;
import boomerang.scene.Statement;
import boomerang.scene.Type;
import boomerang.scene.Val;
import boomerang.solver.BackwardBoomerangSolver;
import boomerang.solver.ForwardBoomerangSolver;
import boomerang.stats.IBoomerangStats;
import boomerang.util.AccessPath;
import boomerang.util.DefaultValueMap;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import sync.pds.solver.nodes.INode;
import sync.pds.solver.nodes.Node;
import wpds.impl.Transition;
import wpds.impl.Weight;
import wpds.impl.WeightedPAutomaton;
public class BackwardBoomerangResults extends AbstractBoomerangResults {
private final BackwardQuery query;
private final BackwardBoomerangSolver backwardSolver;
private Map allocationSites;
private final boolean timedout;
private final IBoomerangStats stats;
private Stopwatch analysisWatch;
private long maxMemory;
public BackwardBoomerangResults(
BackwardQuery query,
boolean timedout,
DefaultValueMap> queryToSolvers,
BackwardBoomerangSolver backwardSolver,
IBoomerangStats stats,
Stopwatch analysisWatch) {
super(queryToSolvers);
this.query = query;
this.timedout = timedout;
this.stats = stats;
this.analysisWatch = analysisWatch;
this.backwardSolver = backwardSolver;
stats.terminated(query, this);
maxMemory = Util.getReallyUsedMemory();
}
public Map getAllocationSites() {
computeAllocations();
return allocationSites;
}
public boolean isTimedout() {
return timedout;
}
public IBoomerangStats getStats() {
return stats;
}
public Stopwatch getAnalysisWatch() {
return analysisWatch;
}
private void computeAllocations() {
if (allocationSites != null) return;
final Set results = Sets.newHashSet();
for (final Entry> fw : queryToSolvers.entrySet()) {
for (INode> node : fw.getValue().getFieldAutomaton().getInitialStates())
fw.getValue()
.getFieldAutomaton()
.registerListener(
new ExtractAllocationSiteStateListener(node, query, (ForwardQuery) fw.getKey()) {
@Override
protected void allocationSiteFound(
ForwardQuery allocationSite, BackwardQuery query) {
results.add(allocationSite);
}
});
}
allocationSites = Maps.newHashMap();
for (ForwardQuery q : results) {
Context context = constructContextGraph(q, query.asNode());
assert allocationSites.get(q) == null;
allocationSites.put(q, context);
}
}
public boolean aliases(Query el) {
for (final ForwardQuery fw : getAllocationSites().keySet()) {
if (queryToSolvers.getOrCreate(fw).getReachedStates().contains(el.asNode())) {
if (queryToSolvers.getOrCreate(fw).reachesNodeWithEmptyField(el.asNode())) {
return true;
}
}
}
return false;
}
@Deprecated
public Set getAllAliases(Edge stmt) {
final Set results = Sets.newHashSet();
for (final ForwardQuery fw : getAllocationSites().keySet()) {
queryToSolvers
.getOrCreate(fw)
.registerListener(
new ExtractAllAliasListener(this.queryToSolvers.get(fw), results, stmt));
}
return results;
}
@Deprecated
public Set getAllAliases() {
return getAllAliases(query.cfgEdge());
}
public boolean isEmpty() {
computeAllocations();
return allocationSites.isEmpty();
}
/**
* Returns the set of types the backward analysis for the triggered query ever propagates.
*
* @return Set of types the backward analysis propagates
*/
public Set getPropagationType() {
Set types = Sets.newHashSet();
for (Transition> t : backwardSolver.getCallAutomaton().getTransitions()) {
if (!t.getStart().fact().isStatic()) types.add(t.getStart().fact().getType());
}
return types;
}
/**
* Computes the set of statements (and variables at these statements) relevant for data-flow
* propagation. A statement s is relevant, if a propagated variable x is used at s. I.e., when
* propagting x @ y = x, the returned set contains x @ y = x, whereas it will not contain a call
* site x @ y = foo(c), because x is not used at the statement.
*
* @return The set of relevant statements during data-flow propagation
*/
@Deprecated
public Set> getDataFlowPath(ForwardQuery query) {
Set> dataFlowPath = Sets.newHashSet();
WeightedPAutomaton, W> callAut =
queryToSolvers.getOrCreate(query).getCallAutomaton();
for (Entry>, W> e :
callAut.getTransitionsToFinalWeights().entrySet()) {
Transition> t = e.getKey();
if (t.getLabel().equals(Statement.epsilon())) continue;
if (t.getStart().fact().isLocal()
&& !t.getLabel().getMethod().equals(t.getStart().fact().m())) continue;
if (t.getLabel().getStart().uses(t.getStart().fact()))
dataFlowPath.add(new Node<>(t.getLabel(), t.getStart().fact()));
}
return dataFlowPath;
}
public long getMaxMemory() {
return maxMemory;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy