use of soot.jimple.spark.pag.LocalVarNode in project soot by Sable.
the class DemandCSPointsTo method processIncomingEdges.
protected void processIncomingEdges(IncomingEdgeHandler h, Stack<VarAndContext> worklist) {
while (!worklist.isEmpty()) {
incrementNodesTraversed();
VarAndContext varAndContext = worklist.pop();
if (DEBUG) {
debugPrint("looking at " + varAndContext);
}
VarNode v = varAndContext.var;
ImmutableStack<Integer> callingContext = varAndContext.context;
Node[] newEdges = pag.allocInvLookup(v);
for (int i = 0; i < newEdges.length; i++) {
AllocNode allocNode = (AllocNode) newEdges[i];
h.handleAlloc(allocNode, varAndContext);
if (h.terminate()) {
return;
}
}
Collection<AssignEdge> assigns = filterAssigns(v, callingContext, true, true);
for (AssignEdge assignEdge : assigns) {
VarNode src = assignEdge.getSrc();
// }
if (h.shouldHandleSrc(src)) {
ImmutableStack<Integer> newContext = callingContext;
if (assignEdge.isParamEdge()) {
if (!callingContext.isEmpty()) {
if (!callEdgeInSCC(assignEdge)) {
assert assignEdge.getCallSite().equals(callingContext.peek()) : assignEdge + " " + callingContext;
newContext = callingContext.pop();
} else {
newContext = popRecursiveCallSites(callingContext);
}
}
// } else if (refiningCallSite) {
// if (!fieldCheckHeuristic.aggressiveVirtCallRefine())
// {
// // throw new CallSiteException();
// }
// }
} else if (assignEdge.isReturnEdge()) {
if (DEBUG)
debugPrint("entering call site " + assignEdge.getCallSite());
// if (!isRecursive(callingContext, assignEdge)) {
// newContext = callingContext.push(assignEdge
// .getCallSite());
// }
newContext = pushWithRecursionCheck(callingContext, assignEdge);
}
if (assignEdge.isParamEdge()) {
Integer callSite = assignEdge.getCallSite();
if (csInfo.isVirtCall(callSite) && !weirdCall(callSite)) {
Set<SootMethod> targets = refineCallSite(callSite, newContext);
if (DEBUG) {
debugPrint(targets.toString());
}
SootMethod targetMethod = ((LocalVarNode) assignEdge.getDst()).getMethod();
if (!targets.contains(targetMethod)) {
if (DEBUG) {
debugPrint("skipping call because of call graph");
}
continue;
}
}
}
if (src instanceof GlobalVarNode) {
newContext = EMPTY_CALLSTACK;
}
h.handleAssignSrc(new VarAndContext(src, newContext), varAndContext, assignEdge);
if (h.terminate()) {
return;
}
}
}
Set<VarNode> matchSources = vMatches.vMatchInvLookup(v);
Node[] loads = pag.loadInvLookup(v);
for (int i = 0; i < loads.length; i++) {
FieldRefNode frNode = (FieldRefNode) loads[i];
final VarNode loadBase = frNode.getBase();
SparkField field = frNode.getField();
// FieldRefNode>(v, frNode);
for (Pair<VarNode, VarNode> store : fieldToStores.get(field)) {
final VarNode storeBase = store.getO2();
final PointsToSetInternal storeBaseP2Set = storeBase.getP2Set();
final PointsToSetInternal loadBaseP2Set = loadBase.getP2Set();
final VarNode matchSrc = store.getO1();
if (matchSources.contains(matchSrc)) {
if (h.shouldHandleSrc(matchSrc)) {
if (DEBUG) {
debugPrint("match source " + matchSrc);
}
PointsToSetInternal intersection = SootUtil.constructIntersection(storeBaseP2Set, loadBaseP2Set, pag);
boolean checkGetfield = fieldCheckHeuristic.validateMatchesForField(field);
h.handleMatchSrc(matchSrc, intersection, loadBase, storeBase, varAndContext, field, checkGetfield);
if (h.terminate())
return;
}
}
}
}
}
}
use of soot.jimple.spark.pag.LocalVarNode in project soot by Sable.
the class DemandCSPointsTo method filterAssigns.
protected Collection<AssignEdge> filterAssigns(final VarNode v, final ImmutableStack<Integer> callingContext, boolean forward, boolean refineVirtCalls) {
Set<AssignEdge> assigns = forward ? csInfo.getAssignEdges(v) : csInfo.getAssignBarEdges(v);
Collection<AssignEdge> realAssigns;
boolean exitNode = forward ? SootUtil.isParamNode(v) : SootUtil.isRetNode(v);
final boolean backward = !forward;
if (exitNode && !callingContext.isEmpty()) {
Integer topCallSite = callingContext.peek();
realAssigns = new ArrayList<AssignEdge>();
for (AssignEdge assignEdge : assigns) {
assert (forward && assignEdge.isParamEdge()) || (backward && assignEdge.isReturnEdge()) : assignEdge;
Integer assignEdgeCallSite = assignEdge.getCallSite();
assert csInfo.getCallSiteTargets(assignEdgeCallSite).contains(((LocalVarNode) v).getMethod()) : assignEdge;
if (topCallSite.equals(assignEdgeCallSite) || callEdgeInSCC(assignEdge)) {
realAssigns.add(assignEdge);
}
}
// assert realAssigns.size() == 1;
} else {
if (assigns.size() > 1) {
realAssigns = new ArrayList<AssignEdge>();
for (AssignEdge assignEdge : assigns) {
boolean enteringCall = forward ? assignEdge.isReturnEdge() : assignEdge.isParamEdge();
if (enteringCall) {
Integer callSite = assignEdge.getCallSite();
if (csInfo.isVirtCall(callSite) && refineVirtCalls) {
Set<SootMethod> targets = refineCallSite(assignEdge.getCallSite(), callingContext);
LocalVarNode nodeInTargetMethod = forward ? (LocalVarNode) assignEdge.getSrc() : (LocalVarNode) assignEdge.getDst();
if (targets.contains(nodeInTargetMethod.getMethod())) {
realAssigns.add(assignEdge);
}
} else {
realAssigns.add(assignEdge);
}
} else {
realAssigns.add(assignEdge);
}
}
} else {
realAssigns = assigns;
}
}
return realAssigns;
}
use of soot.jimple.spark.pag.LocalVarNode in project soot by Sable.
the class DemandCSPointsTo method callEdgeInSCC.
protected boolean callEdgeInSCC(AssignEdge assignEdge) {
boolean sameSCCAlready = false;
assert assignEdge.isCallEdge();
// assignEdge.getSrc() + " not LocalVarNode";
if (!(assignEdge.getSrc() instanceof LocalVarNode) || !(assignEdge.getDst() instanceof LocalVarNode)) {
return false;
}
LocalVarNode src = (LocalVarNode) assignEdge.getSrc();
LocalVarNode dst = (LocalVarNode) assignEdge.getDst();
if (sccManager.inSameSCC(src.getMethod(), dst.getMethod())) {
sameSCCAlready = true;
}
return sameSCCAlready;
}
use of soot.jimple.spark.pag.LocalVarNode in project soot by Sable.
the class DemandCSPointsTo method findVarContextsFromAlloc.
protected CallingContextSet findVarContextsFromAlloc(AllocAndContext allocAndContext, VarNode targetVar) {
CallingContextSet tmpSet = checkAllocAndContextCache(allocAndContext, targetVar);
if (tmpSet != null) {
return tmpSet;
}
CallingContextSet ret = new CallingContextSet();
allocAndContextCache.get(allocAndContext).put(targetVar, ret);
try {
HashSet<VarAndContext> marked = new HashSet<VarAndContext>();
Stack<VarAndContext> worklist = new Stack<VarAndContext>();
Propagator<VarAndContext> p = new Propagator<VarAndContext>(marked, worklist);
AllocNode alloc = allocAndContext.alloc;
ImmutableStack<Integer> allocContext = allocAndContext.context;
Node[] newBarNodes = pag.allocLookup(alloc);
for (int i = 0; i < newBarNodes.length; i++) {
VarNode v = (VarNode) newBarNodes[i];
p.prop(new VarAndContext(v, allocContext));
}
while (!worklist.isEmpty()) {
incrementNodesTraversed();
VarAndContext curVarAndContext = worklist.pop();
if (DEBUG) {
debugPrint("looking at " + curVarAndContext);
}
VarNode curVar = curVarAndContext.var;
ImmutableStack<Integer> curContext = curVarAndContext.context;
if (curVar == targetVar) {
ret.add(curContext);
}
// assign
Collection<AssignEdge> assignEdges = filterAssigns(curVar, curContext, false, true);
for (AssignEdge assignEdge : assignEdges) {
VarNode dst = assignEdge.getDst();
ImmutableStack<Integer> newContext = curContext;
if (assignEdge.isReturnEdge()) {
if (!curContext.isEmpty()) {
if (!callEdgeInSCC(assignEdge)) {
assert assignEdge.getCallSite().equals(curContext.peek()) : assignEdge + " " + curContext;
newContext = curContext.pop();
} else {
newContext = popRecursiveCallSites(curContext);
}
}
} else if (assignEdge.isParamEdge()) {
if (DEBUG)
debugPrint("entering call site " + assignEdge.getCallSite());
// if (!isRecursive(curContext, assignEdge)) {
// newContext = curContext.push(assignEdge
// .getCallSite());
// }
newContext = pushWithRecursionCheck(curContext, assignEdge);
}
if (assignEdge.isReturnEdge() && curContext.isEmpty() && csInfo.isVirtCall(assignEdge.getCallSite())) {
Set<SootMethod> targets = refineCallSite(assignEdge.getCallSite(), newContext);
if (!targets.contains(((LocalVarNode) assignEdge.getDst()).getMethod())) {
continue;
}
}
if (dst instanceof GlobalVarNode) {
newContext = EMPTY_CALLSTACK;
}
p.prop(new VarAndContext(dst, newContext));
}
// putfield_bars
Set<VarNode> matchTargets = vMatches.vMatchLookup(curVar);
Node[] pfTargets = pag.storeLookup(curVar);
for (int i = 0; i < pfTargets.length; i++) {
FieldRefNode frNode = (FieldRefNode) pfTargets[i];
final VarNode storeBase = frNode.getBase();
SparkField field = frNode.getField();
// FieldRefNode>(curVar, frNode);
for (Pair<VarNode, VarNode> load : fieldToLoads.get(field)) {
final VarNode loadBase = load.getO2();
final PointsToSetInternal loadBaseP2Set = loadBase.getP2Set();
final PointsToSetInternal storeBaseP2Set = storeBase.getP2Set();
final VarNode matchTgt = load.getO1();
if (matchTargets.contains(matchTgt)) {
if (DEBUG) {
debugPrint("match source " + matchTgt);
}
PointsToSetInternal intersection = SootUtil.constructIntersection(storeBaseP2Set, loadBaseP2Set, pag);
boolean checkField = fieldCheckHeuristic.validateMatchesForField(field);
if (checkField) {
AllocAndContextSet sharedAllocContexts = findContextsForAllocs(new VarAndContext(storeBase, curContext), intersection);
for (AllocAndContext curAllocAndContext : sharedAllocContexts) {
CallingContextSet upContexts;
if (fieldCheckHeuristic.validFromBothEnds(field)) {
upContexts = findUpContextsForVar(curAllocAndContext, new VarContextAndUp(loadBase, EMPTY_CALLSTACK, EMPTY_CALLSTACK));
} else {
upContexts = findVarContextsFromAlloc(curAllocAndContext, loadBase);
}
for (ImmutableStack<Integer> upContext : upContexts) {
p.prop(new VarAndContext(matchTgt, upContext));
}
}
} else {
p.prop(new VarAndContext(matchTgt, EMPTY_CALLSTACK));
}
// h.handleMatchSrc(matchSrc, intersection,
// storeBase,
// loadBase, varAndContext, checkGetfield);
// if (h.terminate())
// return;
}
}
}
}
return ret;
} catch (CallSiteException e) {
allocAndContextCache.remove(allocAndContext);
throw e;
}
}
use of soot.jimple.spark.pag.LocalVarNode in project soot by Sable.
the class PtInsNode method do_before_propagation.
@Override
public void do_before_propagation() {
// if ( complex_cons == null )
do_pts_interval_merge();
// if ( !(me instanceof LocalVarNode) )
do_flow_edge_interval_merge();
// This pointer filter, please read the comments at this line in file FullSensitiveNode.java
Node wrappedNode = getWrappedNode();
if (wrappedNode instanceof LocalVarNode && ((LocalVarNode) wrappedNode).isThisPtr()) {
SootMethod func = ((LocalVarNode) wrappedNode).getMethod();
if (!func.isConstructor()) {
// We don't process the specialinvoke call edge
SootClass defClass = func.getDeclaringClass();
Hierarchy typeHierarchy = Scene.v().getActiveHierarchy();
for (Iterator<AllocNode> it = new_pts.keySet().iterator(); it.hasNext(); ) {
AllocNode obj = it.next();
if (obj.getType() instanceof RefType) {
SootClass sc = ((RefType) obj.getType()).getSootClass();
if (defClass != sc) {
try {
SootMethod rt_func = typeHierarchy.resolveConcreteDispatch(sc, func);
if (rt_func != func) {
it.remove();
// Also preclude it from propagation again
pt_objs.put(obj, (PtInsIntervalManager) deadManager);
}
} catch (RuntimeException e) {
// If the input program has a wrong type cast, resolveConcreteDispatch fails and it goes here
// We simply ignore this error
}
}
}
}
}
}
}
Aggregations