Search in sources :

Example 1 with BriefUnitGraph

use of soot.toolkits.graph.BriefUnitGraph in project soot by Sable.

the class AugmentedStmtGraph method mirror_PredsSuccs.

private void mirror_PredsSuccs(AugmentedStmt as, UnitGraph ug) {
    Stmt s = as.get_Stmt();
    LinkedList<AugmentedStmt> preds = new LinkedList<AugmentedStmt>(), succs = new LinkedList<AugmentedStmt>();
    // mirror the predecessors
    for (Unit u : ug.getPredsOf(s)) {
        AugmentedStmt po = get_AugStmt((Stmt) u);
        if (preds.contains(po) == false)
            preds.add(po);
    }
    // mirror the successors
    for (Unit u : ug.getSuccsOf(s)) {
        AugmentedStmt so = get_AugStmt((Stmt) u);
        if (succs.contains(so) == false)
            succs.add(so);
    }
    // attach the mirrors properly to the AugmentedStmt
    if (ug instanceof BriefUnitGraph) {
        as.bpreds = preds;
        as.bsuccs = succs;
        if (preds.size() == 0)
            bheads.add(as);
        if (succs.size() == 0)
            btails.add(as);
    } else if (ug instanceof TrapUnitGraph) {
        as.cpreds = preds;
        as.csuccs = succs;
        if (preds.size() == 0)
            cheads.add(as);
        if (succs.size() == 0)
            ctails.add(as);
    } else
        throw new RuntimeException("Unknown UnitGraph type: " + ug.getClass());
}
Also used : TrapUnitGraph(soot.toolkits.graph.TrapUnitGraph) BriefUnitGraph(soot.toolkits.graph.BriefUnitGraph) Unit(soot.Unit) LinkedList(java.util.LinkedList) TableSwitchStmt(soot.jimple.TableSwitchStmt) LookupSwitchStmt(soot.jimple.LookupSwitchStmt) Stmt(soot.jimple.Stmt) IfStmt(soot.jimple.IfStmt)

Example 2 with BriefUnitGraph

use of soot.toolkits.graph.BriefUnitGraph in project soot by Sable.

the class AddSwitches method internalTransform.

protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
    if (b.getMethod().getSignature().indexOf("<clinit>") >= 0)
        return;
    int weight = soot.jbco.Main.getWeight(phaseName, b.getMethod().getSignature());
    if (weight == 0)
        return;
    New2InitFlowAnalysis fa = new New2InitFlowAnalysis(new BriefUnitGraph(b));
    Vector<Unit> zeroheight = new Vector<Unit>();
    PatchingChain<Unit> units = b.getUnits();
    Unit first = null;
    for (Unit unit : units) {
        if (unit instanceof IdentityStmt)
            continue;
        first = unit;
        break;
    }
    Iterator<Unit> it = units.snapshotIterator();
    while (it.hasNext()) {
        Unit unit = (Unit) it.next();
        if (unit instanceof IdentityStmt || checkTraps(unit, b))
            continue;
        // very conservative estimate about where new-<init> ranges are
        if (fa.getFlowAfter(unit).isEmpty() && fa.getFlowBefore(unit).isEmpty()) {
            zeroheight.add(unit);
        }
    }
    if (zeroheight.size() < 3)
        return;
    int idx = 0;
    Unit u = null;
    for (int i = 0; i < zeroheight.size(); i++) {
        idx = Rand.getInt(zeroheight.size() - 1) + 1;
        u = (Unit) zeroheight.get(idx);
        if (u.fallsThrough())
            break;
        u = null;
    }
    // couldn't find a unit that fell through
    if (u == null || Rand.getInt(10) > weight)
        return;
    zeroheight.remove(idx);
    while (zeroheight.size() > (weight > 3 ? weight : 3)) {
        zeroheight.remove(Rand.getInt(zeroheight.size()));
    }
    Collection<Local> locals = b.getLocals();
    List<Unit> targs = new ArrayList<Unit>();
    targs.addAll(zeroheight);
    SootField[] ops = FieldRenamer.getRandomOpaques();
    Local b1 = Jimple.v().newLocal("addswitchesbool1", BooleanType.v());
    locals.add(b1);
    Local b2 = Jimple.v().newLocal("addswitchesbool2", BooleanType.v());
    locals.add(b2);
    if (ops[0].getType() instanceof PrimType) {
        units.insertBefore(Jimple.v().newAssignStmt(b1, Jimple.v().newStaticFieldRef(ops[0].makeRef())), u);
    } else {
        RefType rt = (RefType) ops[0].getType();
        SootMethod m = rt.getSootClass().getMethodByName("booleanValue");
        Local B = Jimple.v().newLocal("addswitchesBOOL1", rt);
        locals.add(B);
        units.insertBefore(Jimple.v().newAssignStmt(B, Jimple.v().newStaticFieldRef(ops[0].makeRef())), u);
        units.insertBefore(Jimple.v().newAssignStmt(b1, Jimple.v().newVirtualInvokeExpr(B, m.makeRef(), Collections.<Value>emptyList())), u);
    }
    if (ops[1].getType() instanceof PrimType) {
        units.insertBefore(Jimple.v().newAssignStmt(b2, Jimple.v().newStaticFieldRef(ops[1].makeRef())), u);
    } else {
        RefType rt = (RefType) ops[1].getType();
        SootMethod m = rt.getSootClass().getMethodByName("booleanValue");
        Local B = Jimple.v().newLocal("addswitchesBOOL2", rt);
        locals.add(B);
        units.insertBefore(Jimple.v().newAssignStmt(B, Jimple.v().newStaticFieldRef(ops[1].makeRef())), u);
        units.insertBefore(Jimple.v().newAssignStmt(b2, Jimple.v().newVirtualInvokeExpr(B, m.makeRef(), Collections.<Value>emptyList())), u);
    }
    IfStmt ifstmt = Jimple.v().newIfStmt(Jimple.v().newNeExpr(b1, b2), u);
    units.insertBefore(ifstmt, u);
    Local l = Jimple.v().newLocal("addswitchlocal", IntType.v());
    locals.add(l);
    units.insertBeforeNoRedirect(Jimple.v().newAssignStmt(l, IntConstant.v(0)), first);
    units.insertAfter(Jimple.v().newTableSwitchStmt(l, 1, zeroheight.size(), targs, u), ifstmt);
    switchesadded += zeroheight.size() + 1;
    Iterator<Unit> tit = targs.iterator();
    while (tit.hasNext()) {
        Unit nxt = (Unit) tit.next();
        if (Rand.getInt(5) < 4) {
            units.insertBefore(Jimple.v().newAssignStmt(l, Jimple.v().newAddExpr(l, IntConstant.v(Rand.getInt(3) + 1))), nxt);
        }
    }
    ifstmt.setTarget(u);
}
Also used : ArrayList(java.util.ArrayList) BriefUnitGraph(soot.toolkits.graph.BriefUnitGraph) Vector(java.util.Vector)

Example 3 with BriefUnitGraph

use of soot.toolkits.graph.BriefUnitGraph in project soot by Sable.

the class MoveLoadsAboveIfs method internalTransform.

protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
    int weight = soot.jbco.Main.getWeight(phaseName, b.getMethod().getSignature());
    if (weight == 0)
        return;
    BriefUnitGraph bug = new BriefUnitGraph(b);
    List<Unit> candidates = new ArrayList<Unit>();
    List<Unit> visited = new ArrayList<Unit>();
    List<Unit> worklist = new ArrayList<Unit>();
    worklist.addAll(bug.getHeads());
    while (worklist.size() > 0) {
        Unit u = (Unit) worklist.remove(0);
        if (visited.contains(u))
            continue;
        visited.add(u);
        List<Unit> succs = bug.getSuccsOf(u);
        if (u instanceof TargetArgInst) {
            if (checkCandidate(succs, bug))
                candidates.add(u);
        }
        for (int i = 0; i < succs.size(); i++) {
            Unit o = succs.get(i);
            if (!visited.contains(o))
                worklist.add(o);
        }
    }
    int orig = movedloads;
    boolean changed = false;
    PatchingChain<Unit> units = b.getUnits();
    for (int i = 0; i < candidates.size(); i++) {
        Unit u = candidates.get(i);
        List<Unit> succs = bug.getSuccsOf(u);
        BLoadInst clone = (BLoadInst) ((BLoadInst) succs.get(0)).clone();
        if (u instanceof IfNonNullInst || u instanceof IfNullInst) {
            if (category(clone.getOpType()) == 2 || Rand.getInt(10) > weight)
                continue;
            units.insertBefore(clone, u);
            units.insertBefore(Baf.v().newSwapInst(RefType.v(), clone.getOpType()), u);
        // units.insertAfter(clone,p);
        // units.insertAfter(Baf.v().newSwapInst(RefType.v(),clone.getOpType()),clone);
        } else if (u instanceof OpTypeArgInst) {
            Type t = ((OpTypeArgInst) u).getOpType();
            if (category(t) == 2 || Rand.getInt(10) > weight)
                continue;
            units.insertBefore(clone, u);
            Type t2 = clone.getOpType();
            Unit dup;
            if (category(t2) == 2) {
                dup = Baf.v().newDup2_x2Inst(t2, null, t, t);
            } else {
                dup = Baf.v().newDup1_x2Inst(t2, t, t);
            }
            units.insertBefore(dup, u);
            units.insertBefore(Baf.v().newPopInst(t2), u);
        /*units.insertAfter(clone,p);
        Type t2 = clone.getOpType();
        Unit dup;
        if (category(t2)==2) {
          dup = Baf.v().newDup2_x2Inst(t2,null,t,t);
        } else {
          dup = Baf.v().newDup1_x2Inst(t2,t,t);
        }
        units.insertAfter(dup,clone);
        units.insertAfter(Baf.v().newPopInst(t2),dup);*/
        } else {
            if (category(clone.getOpType()) == 2 || Rand.getInt(10) > weight)
                continue;
            units.insertBefore(clone, u);
            units.insertBefore(Baf.v().newSwapInst(IntType.v(), clone.getOpType()), u);
        // units.insertAfter(clone,p);
        // units.insertAfter(Baf.v().newSwapInst(IntType.v(),clone.getOpType()),clone);
        }
        movedloads++;
        // remove old loads after the jump
        for (int j = 0; j < succs.size(); j++) {
            Unit suc = (Unit) succs.get(j);
            List<Unit> sucPreds = bug.getPredsOf(suc);
            if (sucPreds.size() > 1) {
                if (suc == ((TargetArgInst) u).getTarget())
                    ((TargetArgInst) u).setTarget((Unit) bug.getSuccsOf(suc).get(0));
                else {
                    units.insertAfter(Baf.v().newGotoInst((Unit) bug.getSuccsOf(suc).get(0)), u);
                }
            } else {
                units.remove(suc);
            }
        }
        if (i < candidates.size() - 1)
            bug = new BriefUnitGraph(b);
        changed = true;
    }
    if (changed) {
        if (output)
            out.println((movedloads - orig) + " loads moved above ifs in " + b.getMethod().getSignature());
        if (debug)
            StackTypeHeightCalculator.calculateStackHeights(b);
    }
}
Also used : BriefUnitGraph(soot.toolkits.graph.BriefUnitGraph)

Example 4 with BriefUnitGraph

use of soot.toolkits.graph.BriefUnitGraph in project soot by Sable.

the class BusyCodeMotion method internalTransform.

/**
 * performs the busy code motion.
 */
protected void internalTransform(Body b, String phaseName, Map<String, String> opts) {
    BCMOptions options = new BCMOptions(opts);
    HashMap<EquivalentValue, Local> expToHelper = new HashMap<EquivalentValue, Local>();
    Chain<Unit> unitChain = b.getUnits();
    if (Options.v().verbose())
        logger.debug("[" + b.getMethod().getName() + "]     performing Busy Code Motion...");
    CriticalEdgeRemover.v().transform(b, phaseName + ".cer");
    UnitGraph graph = new BriefUnitGraph(b);
    /* map each unit to its RHS. only take binary expressions */
    Map<Unit, EquivalentValue> unitToEquivRhs = new UnitMap<EquivalentValue>(b, graph.size() + 1, 0.7f) {

        protected EquivalentValue mapTo(Unit unit) {
            Value tmp = SootFilter.noInvokeRhs(unit);
            Value tmp2 = SootFilter.binop(tmp);
            if (tmp2 == null)
                tmp2 = SootFilter.concreteRef(tmp);
            return SootFilter.equiVal(tmp2);
        }
    };
    /* same as before, but without exception-throwing expressions */
    Map<Unit, EquivalentValue> unitToNoExceptionEquivRhs = new UnitMap<EquivalentValue>(b, graph.size() + 1, 0.7f) {

        protected EquivalentValue mapTo(Unit unit) {
            Value tmp = SootFilter.binopRhs(unit);
            tmp = SootFilter.noExceptionThrowing(tmp);
            return SootFilter.equiVal(tmp);
        }
    };
    /* if a more precise sideeffect-tester comes out, please change it here! */
    SideEffectTester sideEffect;
    if (Scene.v().hasCallGraph() && !options.naive_side_effect()) {
        sideEffect = new PASideEffectTester();
    } else {
        sideEffect = new NaiveSideEffectTester();
    }
    sideEffect.newMethod(b.getMethod());
    UpSafetyAnalysis upSafe = new UpSafetyAnalysis(graph, unitToEquivRhs, sideEffect);
    DownSafetyAnalysis downSafe = new DownSafetyAnalysis(graph, unitToNoExceptionEquivRhs, sideEffect);
    EarliestnessComputation earliest = new EarliestnessComputation(graph, upSafe, downSafe, sideEffect);
    LocalCreation localCreation = new LocalCreation(b.getLocals(), PREFIX);
    Iterator<Unit> unitIt = unitChain.snapshotIterator();
    {
        /* insert the computations at the earliest positions */
        while (unitIt.hasNext()) {
            Unit currentUnit = unitIt.next();
            for (EquivalentValue equiVal : earliest.getFlowBefore(currentUnit)) {
                // Value exp = equiVal.getValue();
                /* get the unic helper-name for this expression */
                Local helper = expToHelper.get(equiVal);
                // the beginning of the method
                if (currentUnit instanceof IdentityStmt)
                    currentUnit = getFirstNonIdentityStmt(b);
                if (helper == null) {
                    helper = localCreation.newLocal(equiVal.getType());
                    expToHelper.put(equiVal, helper);
                }
                /* insert a new Assignment-stmt before the currentUnit */
                Value insertValue = Jimple.cloneIfNecessary(equiVal.getValue());
                Unit firstComp = Jimple.v().newAssignStmt(helper, insertValue);
                unitChain.insertBefore(firstComp, currentUnit);
            }
        }
    }
    {
        /* replace old computations by the helper-vars */
        unitIt = unitChain.iterator();
        while (unitIt.hasNext()) {
            Unit currentUnit = unitIt.next();
            EquivalentValue rhs = unitToEquivRhs.get(currentUnit);
            if (rhs != null) {
                Local helper = expToHelper.get(rhs);
                if (helper != null)
                    ((AssignStmt) currentUnit).setRightOp(helper);
            }
        }
    }
    if (Options.v().verbose())
        logger.debug("[" + b.getMethod().getName() + "]     Busy Code Motion done!");
}
Also used : EquivalentValue(soot.EquivalentValue) PASideEffectTester(soot.jimple.toolkits.pointer.PASideEffectTester) SideEffectTester(soot.SideEffectTester) NaiveSideEffectTester(soot.jimple.NaiveSideEffectTester) BCMOptions(soot.options.BCMOptions) HashMap(java.util.HashMap) PASideEffectTester(soot.jimple.toolkits.pointer.PASideEffectTester) LocalCreation(soot.jimple.toolkits.scalar.LocalCreation) AssignStmt(soot.jimple.AssignStmt) Local(soot.Local) BriefUnitGraph(soot.toolkits.graph.BriefUnitGraph) Unit(soot.Unit) UnitGraph(soot.toolkits.graph.UnitGraph) BriefUnitGraph(soot.toolkits.graph.BriefUnitGraph) EquivalentValue(soot.EquivalentValue) Value(soot.Value) NaiveSideEffectTester(soot.jimple.NaiveSideEffectTester) UnitMap(soot.util.UnitMap) IdentityStmt(soot.jimple.IdentityStmt)

Example 5 with BriefUnitGraph

use of soot.toolkits.graph.BriefUnitGraph in project soot by Sable.

the class NullTransformer method internalTransform.

protected void internalTransform(Body b, String phaseName, java.util.Map options) {
    NullnessAnalysis na = new NullnessAnalysis(new BriefUnitGraph(b));
    java.util.Iterator uIt = b.getUnits().iterator();
    while (uIt.hasNext()) {
        Unit u = (Unit) uIt.next();
        StringBuffer n = new StringBuffer();
        u.addTag(new StringTag("IN: " + na.getFlowBefore(u).toString()));
        if (u.fallsThrough()) {
            ArraySparseSet s = (ArraySparseSet) na.getFallFlowAfter(u);
            u.addTag(new StringTag("FALL: " + s.toString()));
        }
        if (u.branches()) {
            ArraySparseSet t = (ArraySparseSet) na.getBranchFlowAfter(u).get(0);
            u.addTag(new StringTag("BRANCH: " + t.toString()));
        }
    }
}
Also used : StringTag(soot.tagkit.StringTag) ArraySparseSet(soot.toolkits.scalar.ArraySparseSet) BriefUnitGraph(soot.toolkits.graph.BriefUnitGraph) Unit(soot.Unit)

Aggregations

BriefUnitGraph (soot.toolkits.graph.BriefUnitGraph)6 Unit (soot.Unit)3 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 Vector (java.util.Vector)1 EquivalentValue (soot.EquivalentValue)1 Local (soot.Local)1 SideEffectTester (soot.SideEffectTester)1 Value (soot.Value)1 AssignStmt (soot.jimple.AssignStmt)1 IdentityStmt (soot.jimple.IdentityStmt)1 IfStmt (soot.jimple.IfStmt)1 LookupSwitchStmt (soot.jimple.LookupSwitchStmt)1 NaiveSideEffectTester (soot.jimple.NaiveSideEffectTester)1 Stmt (soot.jimple.Stmt)1 TableSwitchStmt (soot.jimple.TableSwitchStmt)1 PASideEffectTester (soot.jimple.toolkits.pointer.PASideEffectTester)1 LocalCreation (soot.jimple.toolkits.scalar.LocalCreation)1 BCMOptions (soot.options.BCMOptions)1