package jqian.sootex.du; import java.util.*; import soot.*; import soot.toolkits.graph.*; import jqian.sootex.location.HeapAbstraction; import jqian.sootex.sideeffect.ISideEffectAnalysis; import jqian.sootex.util.SootUtils; import jqian.sootex.CFGProvider; import jqian.sootex.Cache; import jqian.sootex.ptsto.IPtsToQuery; import jqian.util.Utils; /** * Context-insensitive reaching definition / use analysis * General steps: * 1.a. buildAll(); => build for all reachable methods * b. buildXX(SootMethod) => Just build for a single method. * May need to take care of the build order so that the callees * are always built before their callers. * * 3.a. clear() => clear all used temporal for the whole analysis * b. clear(SootMethod) => clear all temporal used for build the specified method */ public class DUBuilder{ private boolean _verbose; private RDAnalysis[] _rdAnalyses; //Reaching definition analyzer for each method private RUAnalysis[] _ruAnalyses; //Reaching use analyzer for each method private HeapAbstraction _heapAbstraction; //-------------- Temporal ------------------// private IPtsToQuery _ptsto; private ISideEffectAnalysis _sideEffect; private IGlobalDUQuery _query; private CFGProvider _cfgProvider; public DUBuilder(CFGProvider cfgProvider, IPtsToQuery ptsto, HeapAbstraction heapAbstraction, ISideEffectAnalysis sideEffect, boolean verbose){ this._cfgProvider = cfgProvider; this._ptsto = ptsto; this._sideEffect = sideEffect; this._verbose = verbose; this._query = new GbDUQuery(); this._heapAbstraction = heapAbstraction; int methodCount = SootUtils.getMethodCount(); this._rdAnalyses = new RDAnalysis[methodCount]; this._ruAnalyses = new RUAnalysis[methodCount]; } /** Using lazy building, nothing is done at all. */ public void buildAll() { Date startTime = new Date(); List<?> rm = Cache.v().getTopologicalOrder(); for (Iterator<?> it = rm.iterator(); it.hasNext();) { //SootMethod m = (SootMethod) it.next(); //ReachingDefQuery query = gbRdQuery.getQuery(m); //PtsToQuery pt2Query = ptsToQuery.getMethodQuery(m); } Date endTime = new Date(); System.out.println("Test finish in " + Utils.getTimeConsumed(startTime, endTime)); } public void buildRD(SootMethod m){ int id = m.getNumber(); RDAnalysis rdAnalysis = _rdAnalyses[id]; if (rdAnalysis == null) { UnitGraph cfg = _cfgProvider.getCFG(m); rdAnalysis = new RDAnalysis(m, cfg, _ptsto, _heapAbstraction, _sideEffect, _verbose); rdAnalysis.build(); _rdAnalyses[m.getNumber()] = rdAnalysis; } } public void buildRU(SootMethod m){ int id = m.getNumber(); RUAnalysis ruAnalysis = _ruAnalyses[id]; if (ruAnalysis == null) { UnitGraph cfg = _cfgProvider.getCFG(m); ruAnalysis = new RUAnalysis(m, cfg, _ptsto, _heapAbstraction, _sideEffect, _verbose); ruAnalysis.build(); _ruAnalyses[m.getNumber()] = ruAnalysis; } } public void clear(SootMethod m){ } public void clear(){ _ptsto = null; _sideEffect = null; _query = null; _cfgProvider = null; } /** The building result. */ public IGlobalDUQuery getGlobalDUQuery(){ return _query; } ///////////////////////////////////////////////////////////////////////////////////////// public class GbDUQuery implements IGlobalDUQuery{ public IReachingDUQuery getRDQuery(MethodOrMethodContext mc){ SootMethod m = mc.method(); buildRD(m); int id = m.getNumber(); RDAnalysis rdAnalysis = _rdAnalyses[id]; return rdAnalysis; } public IReachingDUQuery getRUQuery(MethodOrMethodContext mc) { SootMethod m = mc.method(); buildRU(m); int id = m.getNumber(); RUAnalysis ruAnalysis = _ruAnalyses[id]; return ruAnalysis; } public void releaseQuery(MethodOrMethodContext mc){ SootMethod m = mc.method(); int id = m.getNumber(); _rdAnalyses[id] = null; _ruAnalyses[id] = null; } } }