package jqian.sootex.dependency;
import java.util.*;
import jqian.sootex.CFGProvider;
import jqian.sootex.du.IGlobalDUQuery;
import jqian.sootex.du.IReachingDUQuery;
import jqian.sootex.location.Location;
import jqian.sootex.util.SootUtils;
import soot.SootMethod;
import soot.Unit;
import soot.toolkits.graph.UnitGraph;
/**
* XXX: This class do not cache data, so, could be very slow if reenter.
*/
public class DependencyQuery implements IDependencyQuery {
private IGlobalDUQuery _duQuery;
private CFGProvider _cfgProvider;
private Map<Unit,Collection<Unit>>[] _method2ctrlDepMap;
@SuppressWarnings("unchecked")
public DependencyQuery(IGlobalDUQuery duQuery, CFGProvider cfgProvider){
this._duQuery = duQuery;
this._cfgProvider = cfgProvider;
this._method2ctrlDepMap = new Map[SootUtils.getMethodCount()];
}
public void release(SootMethod m){
int mId = m.getNumber();
_duQuery.releaseQuery(m);
_method2ctrlDepMap[mId] = null;
}
public Collection<Unit> getCtrlDependences(SootMethod m, Unit u){
int mId = m.getNumber();
Map<Unit,Collection<Unit>> map = _method2ctrlDepMap[mId];
if(map==null){
UnitGraph cfg = _cfgProvider.getCFG(m);
map = DependencyHelper.calcCtrlDependences(cfg);
_method2ctrlDepMap[mId] = map;
}
Collection<Unit> result = map.get(u);
return result;
}
/** Get Write->Read dependences. */
public Collection<Unit> getWRDependences(SootMethod m, Unit u){
IReachingDUQuery rd = _duQuery.getRDQuery(m);
IReachingDUQuery ru = _duQuery.getRUQuery(m);
Collection<Location> usedLocations = ru.getDULocations(u);
Collection<Unit> defs = rd.getReachingDUSites(u, null, usedLocations);
return defs;
}
/** Get Read->Write dependences. */
public Collection<Unit> getRWDependences(SootMethod m, Unit u){
IReachingDUQuery rd = _duQuery.getRDQuery(m);
IReachingDUQuery ru = _duQuery.getRUQuery(m);
Collection<Location> defLocations = rd.getDULocations(u);
Collection<Unit> uses = ru.getReachingDUSites(u, null, defLocations);
return uses;
}
/** Get Write->Write dependences. */
public Collection<Unit> getWWDependences(SootMethod m, Unit u){
IReachingDUQuery rd = _duQuery.getRDQuery(m);
Collection<Location> defLocations = rd.getDULocations(u);
Collection<Unit> defs = rd.getReachingDUSites(u, null, defLocations);
return defs;
}
public Collection<Unit> getAllDependences(SootMethod m, Unit u){
Collection<Unit> cd = getCtrlDependences(m, u);
Collection<Unit> rwd = getRWDependences(m, u);
Collection<Unit> wrd = getWRDependences(m, u);
Collection<Unit> wwd = getWWDependences(m, u);
Collection<Unit> dep = new HashSet<Unit>();
dep.addAll(cd);
dep.addAll(rwd);
dep.addAll(wrd);
dep.addAll(wwd);
return dep;
}
}