All Downloads are FREE. Search and download functionalities are using the official Maven repository.

qilin.pta.toolkits.zipper.analysis.PotentialContextElement Maven / Gradle / Ivy

package qilin.pta.toolkits.zipper.analysis;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import qilin.core.PTA;
import qilin.core.builder.MethodNodeFactory;
import qilin.core.pag.AllocNode;
import qilin.core.pag.ContextMethod;
import qilin.core.pag.VarNode;
import qilin.core.sets.PointsToSet;
import qilin.pta.toolkits.common.OAG;
import qilin.pta.toolkits.zipper.Global;
import qilin.util.collect.SetFactory;
import qilin.util.graph.MergedNode;
import qilin.util.graph.SCCMergedGraph;
import qilin.util.graph.TopologicalSorter;
import sootup.core.model.SootMethod;
import sootup.core.types.Type;

/**
 * For each object o, this class compute the set of methods which o could potentially be their
 * context element.
 *
 * 

Conversely, for each method m, this class compute the set of objects which could potentially * be its context element. */ public class PotentialContextElement { private final PTA pta; // This map maps each object to the methods invoked on it. // For instance methods, they are the methods whose receiver is the object. // For static methods, they are the methods reachable from instance methods. private Map> invokedMethods; private Map> obj2invokedMethods; private final Map> typePCEMethods; private final Map> pceOfMap; private final OAG oag; private final Map> typeAllocatees; private final Map> allocateeMap; PotentialContextElement(final PTA pta, final OAG oag) { this.pta = pta; this.oag = oag; this.typePCEMethods = new ConcurrentHashMap<>(); this.obj2invokedMethods = new ConcurrentHashMap<>(); this.pceOfMap = new ConcurrentHashMap<>(); this.typeAllocatees = new ConcurrentHashMap<>(); this.allocateeMap = new ConcurrentHashMap<>(); this.init(oag); } public Set PCEMethodsOf(final AllocNode obj) { return this.pceOfMap.getOrDefault(obj, Collections.emptySet()); } /** * @param type * @return PCE methods of the objects of given type. */ public Set PCEMethodsOf(final Type type) { if (!this.typePCEMethods.containsKey(type)) { final Set methods = ConcurrentHashMap.newKeySet(); pta.getPag().getAllocNodes().stream() .filter(o -> o.getType().equals(type)) .forEach(obj -> methods.addAll(this.PCEMethodsOf(obj))); this.typePCEMethods.put(type, methods); } return this.typePCEMethods.getOrDefault(type, Collections.emptySet()); } /** Compute PCE methods for each objects. */ private void init(final OAG oag) { final SCCMergedGraph mg = new SCCMergedGraph<>(oag); final TopologicalSorter> topoSorter = new TopologicalSorter<>(); final SetFactory setFactory = new SetFactory<>(); final SetFactory setFactory2 = new SetFactory<>(); this.buildMethodsInvokedOnObjects(); this.invokedMethods = new HashMap<>(); topoSorter .sort(mg, true) .forEach( node -> { final Set methods = ConcurrentHashMap.newKeySet(); methods.addAll(setFactory.get(this.getPCEMethods(node, mg))); final Set allocatees = ConcurrentHashMap.newKeySet(); allocatees.addAll(setFactory2.get(this.getAllocatees(node, mg))); node.getContent() .forEach( obj -> { pceOfMap.put(obj, methods); allocateeMap.put(obj, allocatees); }); }); this.invokedMethods = null; if (Global.isDebug()) { this.computePCEObjects(); } oag.allNodes() .forEach( obj -> { final Type type = obj.getType(); this.typeAllocatees.putIfAbsent(type, new HashSet<>()); this.typeAllocatees.get(type).addAll(this.allocateesOf(obj)); }); } private Set getAllocatees( final MergedNode node, final SCCMergedGraph mg) { final Set allocatees = new HashSet<>(); mg.succsOf(node) .forEach( n -> { // direct allocatees allocatees.addAll(n.getContent()); // indirect allocatees, here, it does not require to traverse all heaps in // n.getContent() // because of lines 104-107. final AllocNode o = n.getContent().iterator().next(); allocatees.addAll(this.allocateesOf(o)); }); final AllocNode obj = node.getContent().iterator().next(); if (node.getContent().size() > 1 || oag.succsOf(obj).contains(obj)) { // The merged node is a true SCC allocatees.addAll(node.getContent()); } return allocatees; } private Set allocateesOf(final AllocNode obj) { return this.allocateeMap.getOrDefault(obj, Collections.emptySet()); } public Set allocateesOf(final Type type) { return this.typeAllocatees.getOrDefault(type, Collections.emptySet()); } private Set getPCEMethods( final MergedNode node, final SCCMergedGraph mg) { final Set methods = new HashSet<>(); mg.succsOf(node) .forEach( n -> { final AllocNode o2 = n.getContent().iterator().next(); methods.addAll(this.PCEMethodsOf(o2)); }); node.getContent().forEach(o -> methods.addAll(this.invokedMethodsOf(o))); return methods; } public Set methodsInvokedOn(final AllocNode obj) { return this.obj2invokedMethods.getOrDefault(obj, Collections.emptySet()); } private void buildMethodsInvokedOnObjects() { this.obj2invokedMethods = new HashMap<>(); pta.getNakedReachableMethods().stream() .filter(m -> !m.isStatic()) .forEach( instMtd -> { MethodNodeFactory mthdNF = pta.getPag().getMethodPAG(instMtd).nodeFactory(); VarNode thisVar = mthdNF.caseThis(); PointsToSet pts = pta.reachingObjects(thisVar).toCIPointsToSet(); for (Iterator it = pts.iterator(); it.hasNext(); ) { AllocNode obj = it.next(); obj2invokedMethods.computeIfAbsent(obj, k -> new HashSet<>()).add(instMtd); } }); } private Set invokedMethodsOf(final AllocNode obj) { if (!this.invokedMethods.containsKey(obj)) { final Set methods = new HashSet<>(); final Queue queue = new LinkedList<>(this.methodsInvokedOn(obj)); while (!queue.isEmpty()) { final SootMethod method = queue.poll(); methods.add(method); pta.getCallGraph() .edgesOutOf(new ContextMethod(method, pta.emptyContext())) .forEachRemaining( edge -> { SootMethod callee = edge.getTgt().method(); if (callee.isStatic() && !methods.contains(callee)) { queue.offer(callee); } }); } this.invokedMethods.put(obj, methods); } return this.invokedMethods.get(obj); } private void computePCEObjects() { final Map> pceObjs = new HashMap<>(); pta.getPag() .getAllocNodes() .forEach( obj -> this.PCEMethodsOf(obj) .forEach( method -> { if (!pceObjs.containsKey(method)) { pceObjs.put(method, new HashSet<>()); } pceObjs.get(method).add(obj); })); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy