Search in sources :

Example 1 with HybridPointsToSet

use of soot.jimple.spark.sets.HybridPointsToSet in project soot by Sable.

the class DemandCSPointsTo method findContextsForAllocs.

protected AllocAndContextSet findContextsForAllocs(final VarAndContext varAndContext, PointsToSetInternal locs) {
    if (contextForAllocsStack.contains(varAndContext)) {
        // recursion; check depth
        // we're fine for x = x.next
        int oldIndex = contextForAllocsStack.indexOf(varAndContext);
        if (oldIndex != contextForAllocsStack.size() - 1) {
            if (recursionDepth == -1) {
                recursionDepth = oldIndex + 1;
                if (DEBUG) {
                    debugPrint("RECURSION depth = " + recursionDepth);
                }
            } else if (contextForAllocsStack.size() - oldIndex > 5) {
                // just give up
                throw new TerminateEarlyException();
            }
        }
    }
    contextForAllocsStack.push(varAndContext);
    final AllocAndContextSet ret = new AllocAndContextSet();
    final PointsToSetInternal realLocs = checkContextsForAllocsCache(varAndContext, ret, locs);
    if (realLocs.isEmpty()) {
        if (DEBUG) {
            debugPrint("cached result " + ret);
        }
        contextForAllocsStack.pop();
        return ret;
    }
    nesting++;
    if (DEBUG) {
        debugPrint("finding alloc contexts for " + varAndContext);
    }
    try {
        final Set<VarAndContext> marked = new HashSet<VarAndContext>();
        final Stack<VarAndContext> worklist = new Stack<VarAndContext>();
        final Propagator<VarAndContext> p = new Propagator<VarAndContext>(marked, worklist);
        p.prop(varAndContext);
        IncomingEdgeHandler edgeHandler = new IncomingEdgeHandler() {

            @Override
            public void handleAlloc(AllocNode allocNode, VarAndContext origVarAndContext) {
                if (realLocs.contains(allocNode)) {
                    if (DEBUG) {
                        debugPrint("found alloc " + allocNode);
                    }
                    ret.add(new AllocAndContext(allocNode, origVarAndContext.context));
                }
            }

            @Override
            public void handleMatchSrc(final VarNode matchSrc, PointsToSetInternal intersection, VarNode loadBase, VarNode storeBase, VarAndContext origVarAndContext, SparkField field, boolean refine) {
                if (DEBUG) {
                    debugPrint("handling src " + matchSrc);
                    debugPrint("intersection " + intersection);
                }
                if (!refine) {
                    p.prop(new VarAndContext(matchSrc, EMPTY_CALLSTACK));
                    return;
                }
                AllocAndContextSet allocContexts = findContextsForAllocs(new VarAndContext(loadBase, origVarAndContext.context), intersection);
                if (DEBUG) {
                    debugPrint("alloc contexts " + allocContexts);
                }
                for (AllocAndContext allocAndContext : allocContexts) {
                    if (DEBUG) {
                        debugPrint("alloc and context " + allocAndContext);
                    }
                    CallingContextSet matchSrcContexts;
                    if (fieldCheckHeuristic.validFromBothEnds(field)) {
                        matchSrcContexts = findUpContextsForVar(allocAndContext, new VarContextAndUp(storeBase, EMPTY_CALLSTACK, EMPTY_CALLSTACK));
                    } else {
                        matchSrcContexts = findVarContextsFromAlloc(allocAndContext, storeBase);
                    }
                    for (ImmutableStack<Integer> matchSrcContext : matchSrcContexts) {
                        // ret
                        // .add(new Pair<AllocNode,
                        // ImmutableStack<Integer>>(
                        // (AllocNode) n,
                        // matchSrcContext));
                        // ret.addAll(findContextsForAllocs(matchSrc,
                        // matchSrcContext, locs));
                        p.prop(new VarAndContext(matchSrc, matchSrcContext));
                    }
                }
            }

            @Override
            Object getResult() {
                return ret;
            }

            @Override
            void handleAssignSrc(VarAndContext newVarAndContext, VarAndContext origVarAndContext, AssignEdge assignEdge) {
                p.prop(newVarAndContext);
            }

            @Override
            boolean shouldHandleSrc(VarNode src) {
                return realLocs.hasNonEmptyIntersection(src.getP2Set());
            }
        };
        processIncomingEdges(edgeHandler, worklist);
        // update the cache
        if (recursionDepth != -1) {
            // if we're beyond recursion, don't cache anything
            if (contextForAllocsStack.size() > recursionDepth) {
                if (DEBUG) {
                    debugPrint("REMOVING " + varAndContext);
                    debugPrint(contextForAllocsStack.toString());
                }
                contextsForAllocsCache.remove(varAndContext);
            } else {
                assert contextForAllocsStack.size() == recursionDepth : recursionDepth + " " + contextForAllocsStack;
                recursionDepth = -1;
                if (contextsForAllocsCache.containsKey(varAndContext)) {
                    contextsForAllocsCache.get(varAndContext).getO2().addAll(ret);
                } else {
                    PointsToSetInternal storedSet = new HybridPointsToSet(locs.getType(), pag);
                    storedSet.addAll(locs, null);
                    contextsForAllocsCache.put(varAndContext, new Pair<PointsToSetInternal, AllocAndContextSet>(storedSet, ret));
                }
            }
        } else {
            if (contextsForAllocsCache.containsKey(varAndContext)) {
                contextsForAllocsCache.get(varAndContext).getO2().addAll(ret);
            } else {
                PointsToSetInternal storedSet = new HybridPointsToSet(locs.getType(), pag);
                storedSet.addAll(locs, null);
                contextsForAllocsCache.put(varAndContext, new Pair<PointsToSetInternal, AllocAndContextSet>(storedSet, ret));
            }
        }
        nesting--;
        return ret;
    } catch (CallSiteException e) {
        contextsForAllocsCache.remove(varAndContext);
        throw e;
    } finally {
        contextForAllocsStack.pop();
    }
}
Also used : GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) VarNode(soot.jimple.spark.pag.VarNode) PointsToSetInternal(soot.jimple.spark.sets.PointsToSetInternal) SparkField(soot.jimple.spark.pag.SparkField) AssignEdge(soot.jimple.spark.ondemand.pautil.AssignEdge) HybridPointsToSet(soot.jimple.spark.sets.HybridPointsToSet) Stack(soot.jimple.spark.ondemand.genericutil.Stack) ImmutableStack(soot.jimple.spark.ondemand.genericutil.ImmutableStack) AllocNode(soot.jimple.spark.pag.AllocNode) Propagator(soot.jimple.spark.ondemand.genericutil.Propagator) HashSet(java.util.HashSet)

Example 2 with HybridPointsToSet

use of soot.jimple.spark.sets.HybridPointsToSet in project soot by Sable.

the class DemandCSPointsTo method findUpContextsForVar.

protected CallingContextSet findUpContextsForVar(AllocAndContext allocAndContext, VarContextAndUp varContextAndUp) {
    final AllocNode alloc = allocAndContext.alloc;
    final ImmutableStack<Integer> allocContext = allocAndContext.context;
    CallingContextSet tmpSet = checkUpContextCache(varContextAndUp, allocAndContext);
    if (tmpSet != null) {
        return tmpSet;
    }
    final CallingContextSet ret = new CallingContextSet();
    upContextCache.get(varContextAndUp).put(allocAndContext, ret);
    nesting++;
    if (DEBUG) {
        debugPrint("finding up context for " + varContextAndUp + " to " + alloc + " " + allocContext);
    }
    try {
        final Set<VarAndContext> marked = new HashSet<VarAndContext>();
        final Stack<VarAndContext> worklist = new Stack<VarAndContext>();
        final Propagator<VarAndContext> p = new Propagator<VarAndContext>(marked, worklist);
        p.prop(varContextAndUp);
        class UpContextEdgeHandler extends IncomingEdgeHandler {

            @Override
            public void handleAlloc(AllocNode allocNode, VarAndContext origVarAndContext) {
                VarContextAndUp contextAndUp = (VarContextAndUp) origVarAndContext;
                if (allocNode == alloc) {
                    if (allocContext.topMatches(contextAndUp.context)) {
                        ImmutableStack<Integer> reverse = contextAndUp.upContext.reverse();
                        ImmutableStack<Integer> toAdd = allocContext.popAll(contextAndUp.context).pushAll(reverse);
                        if (DEBUG) {
                            debugPrint("found up context " + toAdd);
                        }
                        ret.add(toAdd);
                    } else if (contextAndUp.context.topMatches(allocContext)) {
                        ImmutableStack<Integer> toAdd = contextAndUp.upContext.reverse();
                        if (DEBUG) {
                            debugPrint("found up context " + toAdd);
                        }
                        ret.add(toAdd);
                    }
                }
            }

            @Override
            public void handleMatchSrc(VarNode matchSrc, PointsToSetInternal intersection, VarNode loadBase, VarNode storeBase, VarAndContext origVarAndContext, SparkField field, boolean refine) {
                VarContextAndUp contextAndUp = (VarContextAndUp) origVarAndContext;
                if (DEBUG) {
                    debugPrint("CHECKING " + alloc);
                }
                PointsToSetInternal tmp = new HybridPointsToSet(alloc.getType(), pag);
                tmp.add(alloc);
                AllocAndContextSet allocContexts = findContextsForAllocs(new VarAndContext(matchSrc, EMPTY_CALLSTACK), tmp);
                // Set allocContexts = Collections.singleton(new Object());
                if (!refine) {
                    if (!allocContexts.isEmpty()) {
                        ret.add(contextAndUp.upContext.reverse());
                    }
                } else {
                    if (!allocContexts.isEmpty()) {
                        for (AllocAndContext t : allocContexts) {
                            ImmutableStack<Integer> discoveredAllocContext = t.context;
                            if (!allocContext.topMatches(discoveredAllocContext)) {
                                continue;
                            }
                            ImmutableStack<Integer> trueAllocContext = allocContext.popAll(discoveredAllocContext);
                            AllocAndContextSet allocAndContexts = findContextsForAllocs(new VarAndContext(storeBase, trueAllocContext), intersection);
                            for (AllocAndContext allocAndContext : allocAndContexts) {
                                // CallingContextSet upContexts;
                                if (fieldCheckHeuristic.validFromBothEnds(field)) {
                                    ret.addAll(findUpContextsForVar(allocAndContext, new VarContextAndUp(loadBase, contextAndUp.context, contextAndUp.upContext)));
                                } else {
                                    CallingContextSet tmpContexts = findVarContextsFromAlloc(allocAndContext, loadBase);
                                    // upContexts = new CallingContextSet();
                                    for (ImmutableStack<Integer> tmpContext : tmpContexts) {
                                        if (tmpContext.topMatches(contextAndUp.context)) {
                                            ImmutableStack<Integer> reverse = contextAndUp.upContext.reverse();
                                            ImmutableStack<Integer> toAdd = tmpContext.popAll(contextAndUp.context).pushAll(reverse);
                                            ret.add(toAdd);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            @Override
            Object getResult() {
                return ret;
            }

            @Override
            void handleAssignSrc(VarAndContext newVarAndContext, VarAndContext origVarAndContext, AssignEdge assignEdge) {
                VarContextAndUp contextAndUp = (VarContextAndUp) origVarAndContext;
                ImmutableStack<Integer> upContext = contextAndUp.upContext;
                ImmutableStack<Integer> newUpContext = upContext;
                if (assignEdge.isParamEdge() && contextAndUp.context.isEmpty()) {
                    if (upContext.size() < ImmutableStack.getMaxSize()) {
                        newUpContext = pushWithRecursionCheck(upContext, assignEdge);
                    }
                    ;
                }
                p.prop(new VarContextAndUp(newVarAndContext.var, newVarAndContext.context, newUpContext));
            }

            @Override
            boolean shouldHandleSrc(VarNode src) {
                if (src instanceof GlobalVarNode) {
                    // // for now, just give up
                    throw new TerminateEarlyException();
                }
                return src.getP2Set().contains(alloc);
            }
        }
        ;
        UpContextEdgeHandler edgeHandler = new UpContextEdgeHandler();
        processIncomingEdges(edgeHandler, worklist);
        nesting--;
        // }
        return ret;
    } catch (CallSiteException e) {
        upContextCache.remove(varContextAndUp);
        throw e;
    }
}
Also used : GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) SparkField(soot.jimple.spark.pag.SparkField) AssignEdge(soot.jimple.spark.ondemand.pautil.AssignEdge) Propagator(soot.jimple.spark.ondemand.genericutil.Propagator) ImmutableStack(soot.jimple.spark.ondemand.genericutil.ImmutableStack) HashSet(java.util.HashSet) GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) VarNode(soot.jimple.spark.pag.VarNode) PointsToSetInternal(soot.jimple.spark.sets.PointsToSetInternal) HybridPointsToSet(soot.jimple.spark.sets.HybridPointsToSet) Stack(soot.jimple.spark.ondemand.genericutil.Stack) ImmutableStack(soot.jimple.spark.ondemand.genericutil.ImmutableStack) AllocNode(soot.jimple.spark.pag.AllocNode)

Example 3 with HybridPointsToSet

use of soot.jimple.spark.sets.HybridPointsToSet in project soot by Sable.

the class DemandCSPointsTo method checkContextsForAllocsCache.

protected PointsToSetInternal checkContextsForAllocsCache(VarAndContext varAndContext, AllocAndContextSet ret, PointsToSetInternal locs) {
    PointsToSetInternal retSet = null;
    if (contextsForAllocsCache.containsKey(varAndContext)) {
        for (AllocAndContext allocAndContext : contextsForAllocsCache.get(varAndContext).getO2()) {
            if (locs.contains(allocAndContext.alloc)) {
                ret.add(allocAndContext);
            }
        }
        final PointsToSetInternal oldLocs = contextsForAllocsCache.get(varAndContext).getO1();
        final PointsToSetInternal tmpSet = new HybridPointsToSet(locs.getType(), pag);
        locs.forall(new P2SetVisitor() {

            @Override
            public void visit(Node n) {
                if (!oldLocs.contains(n)) {
                    tmpSet.add(n);
                }
            }
        });
        retSet = tmpSet;
        oldLocs.addAll(tmpSet, null);
    } else {
        PointsToSetInternal storedSet = new HybridPointsToSet(locs.getType(), pag);
        storedSet.addAll(locs, null);
        contextsForAllocsCache.put(varAndContext, new Pair<PointsToSetInternal, AllocAndContextSet>(storedSet, new AllocAndContextSet()));
        retSet = locs;
    }
    return retSet;
}
Also used : PointsToSetInternal(soot.jimple.spark.sets.PointsToSetInternal) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) Node(soot.jimple.spark.pag.Node) VarNode(soot.jimple.spark.pag.VarNode) AllocNode(soot.jimple.spark.pag.AllocNode) HybridPointsToSet(soot.jimple.spark.sets.HybridPointsToSet) P2SetVisitor(soot.jimple.spark.sets.P2SetVisitor)

Example 4 with HybridPointsToSet

use of soot.jimple.spark.sets.HybridPointsToSet in project soot by Sable.

the class SootUtil method constructIntersection.

public static PointsToSetInternal constructIntersection(final PointsToSetInternal set1, final PointsToSetInternal set2, PAG pag) {
    HybridPointsToSet hybridSet1 = null, hybridSet2 = null;
    hybridSet1 = convertToHybrid(set1);
    hybridSet2 = convertToHybrid(set2);
    HybridPointsToSet intersection = HybridPointsToSet.intersection(hybridSet1, hybridSet2, pag);
    // checkSetsEqual(intersection, set1, set2, pag);
    return intersection;
}
Also used : HybridPointsToSet(soot.jimple.spark.sets.HybridPointsToSet)

Example 5 with HybridPointsToSet

use of soot.jimple.spark.sets.HybridPointsToSet in project soot by Sable.

the class SootUtil method checkSetsEqual.

@SuppressWarnings("unused")
private static void checkSetsEqual(final HybridPointsToSet intersection, final PointsToSetInternal set1, final PointsToSetInternal set2, PAG pag) {
    final PointsToSetInternal ret = new HybridPointsToSet(Scene.v().getObjectType(), pag);
    set1.forall(new P2SetVisitor() {

        @Override
        public void visit(Node n) {
            if (set2.contains(n))
                ret.add(n);
        }
    });
    ret.forall(new P2SetVisitor() {

        @Override
        public void visit(Node n) {
            // TODO Auto-generated method stub
            if (!intersection.contains(n)) {
                logger.debug("" + n + " missing from intersection");
                logger.debug("" + set1);
                logger.debug("" + set2);
                logger.debug("" + intersection);
                logger.debug("" + ret);
                throw new RuntimeException("intersection too small");
            }
        }
    });
    intersection.forall(new P2SetVisitor() {

        @Override
        public void visit(Node n) {
            // TODO Auto-generated method stub
            if (!ret.contains(n)) {
                logger.debug("" + n + " missing from ret");
                logger.debug("" + set1);
                logger.debug("" + set2);
                logger.debug("" + intersection);
                logger.debug("" + ret);
                throw new RuntimeException("old way too small???");
            }
        }
    });
}
Also used : PointsToSetInternal(soot.jimple.spark.sets.PointsToSetInternal) FieldRefNode(soot.jimple.spark.pag.FieldRefNode) GlobalVarNode(soot.jimple.spark.pag.GlobalVarNode) StringConstantNode(soot.jimple.spark.pag.StringConstantNode) LocalVarNode(soot.jimple.spark.pag.LocalVarNode) Node(soot.jimple.spark.pag.Node) VarNode(soot.jimple.spark.pag.VarNode) AllocNode(soot.jimple.spark.pag.AllocNode) HybridPointsToSet(soot.jimple.spark.sets.HybridPointsToSet) P2SetVisitor(soot.jimple.spark.sets.P2SetVisitor)

Aggregations

HybridPointsToSet (soot.jimple.spark.sets.HybridPointsToSet)5 AllocNode (soot.jimple.spark.pag.AllocNode)4 GlobalVarNode (soot.jimple.spark.pag.GlobalVarNode)4 LocalVarNode (soot.jimple.spark.pag.LocalVarNode)4 VarNode (soot.jimple.spark.pag.VarNode)4 PointsToSetInternal (soot.jimple.spark.sets.PointsToSetInternal)4 HashSet (java.util.HashSet)2 ImmutableStack (soot.jimple.spark.ondemand.genericutil.ImmutableStack)2 Propagator (soot.jimple.spark.ondemand.genericutil.Propagator)2 Stack (soot.jimple.spark.ondemand.genericutil.Stack)2 AssignEdge (soot.jimple.spark.ondemand.pautil.AssignEdge)2 FieldRefNode (soot.jimple.spark.pag.FieldRefNode)2 Node (soot.jimple.spark.pag.Node)2 SparkField (soot.jimple.spark.pag.SparkField)2 P2SetVisitor (soot.jimple.spark.sets.P2SetVisitor)2 StringConstantNode (soot.jimple.spark.pag.StringConstantNode)1