Search in sources :

Example 36 with Unit

use of soot.Unit in project soot by Sable.

the class JimpleLocal method convertToBaf.

@Override
public void convertToBaf(JimpleToBafContext context, List<Unit> out) {
    Unit u = Baf.v().newLoadInst(getType(), context.getBafLocalOfJimpleLocal(this));
    u.addAllTagsOf(context.getCurrentUnit());
    out.add(u);
}
Also used : Unit(soot.Unit)

Example 37 with Unit

use of soot.Unit in project soot by Sable.

the class ArrayIndexLivenessAnalysis method getGenAndKillSet.

private void getGenAndKillSet(Body body, HashMap<Stmt, HashSet<Value>> absgen, HashMap<Stmt, HashSet<Object>> gen, HashMap<Stmt, HashSet<Value>> kill, HashMap<Stmt, HashSet<Value>> condition) {
    for (Unit u : body.getUnits()) {
        Stmt stmt = (Stmt) u;
        HashSet<Object> genset = new HashSet<Object>();
        HashSet<Value> absgenset = new HashSet<Value>();
        HashSet<Value> killset = new HashSet<Value>();
        HashSet<Value> condset = new HashSet<Value>();
        if (stmt instanceof DefinitionStmt) {
            getGenAndKillSetForDefnStmt((DefinitionStmt) stmt, absgen, genset, absgenset, killset, condset);
        } else if (stmt instanceof IfStmt) {
            /* if one of condition is living, than other one is live. */
            Value cmpcond = ((IfStmt) stmt).getCondition();
            if (cmpcond instanceof ConditionExpr) {
                Value op1 = ((ConditionExpr) cmpcond).getOp1();
                Value op2 = ((ConditionExpr) cmpcond).getOp2();
                if (fullSet.contains(op1) && fullSet.contains(op2)) {
                    condset.add(op1);
                    condset.add(op2);
                    genset.add(op1);
                    genset.add(op2);
                }
            }
        }
        if (genset.size() != 0)
            gen.put(stmt, genset);
        if (absgenset.size() != 0)
            absgen.put(stmt, absgenset);
        if (killset.size() != 0)
            kill.put(stmt, killset);
        if (condset.size() != 0)
            condition.put(stmt, condset);
    }
}
Also used : IfStmt(soot.jimple.IfStmt) ConditionExpr(soot.jimple.ConditionExpr) Value(soot.Value) Unit(soot.Unit) DefinitionStmt(soot.jimple.DefinitionStmt) IfStmt(soot.jimple.IfStmt) Stmt(soot.jimple.Stmt) DefinitionStmt(soot.jimple.DefinitionStmt) HashSet(java.util.HashSet)

Example 38 with Unit

use of soot.Unit in project soot by Sable.

the class MultiRunStatementsFinder method findMultiCalledMethodsIntra.

private void findMultiCalledMethodsIntra(Set<SootMethod> multiCalledMethods, CallGraph callGraph) {
    Iterator<Unit> it = multiRunStatements.iterator();
    while (it.hasNext()) {
        Stmt stmt = (Stmt) it.next();
        if (stmt.containsInvokeExpr()) {
            InvokeExpr invokeExpr = stmt.getInvokeExpr();
            List<SootMethod> targetList = new ArrayList<SootMethod>();
            SootMethod method = invokeExpr.getMethod();
            if (invokeExpr instanceof StaticInvokeExpr) {
                targetList.add(method);
            } else if (invokeExpr instanceof InstanceInvokeExpr) {
                if (method.isConcrete() && !method.getDeclaringClass().isLibraryClass()) {
                    TargetMethodsFinder tmd = new TargetMethodsFinder();
                    targetList = tmd.find(stmt, callGraph, true, true);
                }
            }
            if (targetList != null) {
                Iterator<SootMethod> iterator = targetList.iterator();
                while (iterator.hasNext()) {
                    SootMethod obj = iterator.next();
                    if (!obj.isNative()) {
                        multiCalledMethods.add(obj);
                    }
                }
            }
        }
    }
}
Also used : StaticInvokeExpr(soot.jimple.StaticInvokeExpr) TargetMethodsFinder(soot.jimple.toolkits.thread.mhp.TargetMethodsFinder) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) StaticInvokeExpr(soot.jimple.StaticInvokeExpr) InvokeExpr(soot.jimple.InvokeExpr) ArrayList(java.util.ArrayList) SootMethod(soot.SootMethod) InstanceInvokeExpr(soot.jimple.InstanceInvokeExpr) Unit(soot.Unit) Stmt(soot.jimple.Stmt)

Example 39 with Unit

use of soot.Unit in project soot by Sable.

the class DeadAssignmentEliminator method internalTransform.

/**
 * Eliminates dead code in a linear fashion.  Complexity is linear
 * with respect to the statements.
 *
 * Does not work on grimp code because of the check on the right hand
 * side for side effects.
 */
@Override
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
    boolean eliminateOnlyStackLocals = PhaseOptions.getBoolean(options, "only-stack-locals");
    final Options soptions = Options.v();
    if (soptions.verbose()) {
        logger.debug("[" + b.getMethod().getName() + "] Eliminating dead code...");
    }
    if (soptions.time()) {
        Timers.v().deadCodeTimer.start();
    }
    Chain<Unit> units = b.getUnits();
    Deque<Unit> q = new ArrayDeque<Unit>(units.size());
    // Make a first pass through the statements, noting
    // the statements we must absolutely keep.
    boolean isStatic = b.getMethod().isStatic();
    boolean allEssential = true;
    boolean checkInvoke = false;
    Local thisLocal = null;
    for (Iterator<Unit> it = units.iterator(); it.hasNext(); ) {
        Unit s = it.next();
        boolean isEssential = true;
        if (s instanceof NopStmt) {
            // Hack: do not remove nop if is is used for a Trap
            // which is at the very end of the code.
            boolean removeNop = it.hasNext();
            if (!removeNop) {
                removeNop = true;
                for (Trap t : b.getTraps()) {
                    if (t.getEndUnit() == s) {
                        removeNop = false;
                        break;
                    }
                }
            }
            if (removeNop) {
                it.remove();
                continue;
            }
        } else if (s instanceof AssignStmt) {
            AssignStmt as = (AssignStmt) s;
            Value lhs = as.getLeftOp();
            Value rhs = as.getRightOp();
            // Stmt is of the form a = a which is useless
            if (lhs == rhs && lhs instanceof Local) {
                it.remove();
                continue;
            }
            if (lhs instanceof Local && (!eliminateOnlyStackLocals || ((Local) lhs).getName().startsWith("$") || lhs.getType() instanceof NullType)) {
                isEssential = false;
                if (!checkInvoke) {
                    checkInvoke = as.containsInvokeExpr();
                }
                if (rhs instanceof CastExpr) {
                    // CastExpr          : can trigger ClassCastException, but null-casts never fail
                    CastExpr ce = (CastExpr) rhs;
                    Type t = ce.getCastType();
                    Value v = ce.getOp();
                    isEssential = !(v instanceof NullConstant && t instanceof RefType);
                } else if (rhs instanceof InvokeExpr || rhs instanceof ArrayRef || rhs instanceof NewExpr || rhs instanceof NewArrayExpr || rhs instanceof NewMultiArrayExpr) {
                    // ArrayRef          : can have side effects (like throwing a null pointer exception)
                    // InvokeExpr        : can have side effects (like throwing a null pointer exception)
                    // NewArrayExpr      : can throw exception
                    // NewMultiArrayExpr : can throw exception
                    // NewExpr           : can trigger class initialization
                    isEssential = true;
                } else if (rhs instanceof FieldRef) {
                    // Can trigger class initialization
                    isEssential = true;
                    if (rhs instanceof InstanceFieldRef) {
                        InstanceFieldRef ifr = (InstanceFieldRef) rhs;
                        if (!isStatic && thisLocal == null) {
                            thisLocal = b.getThisLocal();
                        }
                        // Any InstanceFieldRef may have side effects,
                        // unless the base is reading from 'this'
                        // in a non-static method
                        isEssential = (isStatic || thisLocal != ifr.getBase());
                    }
                } else if (rhs instanceof DivExpr || rhs instanceof RemExpr) {
                    BinopExpr expr = (BinopExpr) rhs;
                    Type t1 = expr.getOp1().getType();
                    Type t2 = expr.getOp2().getType();
                    // Can trigger a division by zero
                    boolean t2Int = t2 instanceof IntType;
                    isEssential = t2Int || t1 instanceof IntType || t1 instanceof LongType || t2 instanceof LongType || t1 instanceof UnknownType || t2 instanceof UnknownType;
                    if (isEssential && t2Int) {
                        Value v = expr.getOp2();
                        if (v instanceof IntConstant) {
                            IntConstant i = (IntConstant) v;
                            isEssential = (i.value == 0);
                        } else
                            // could be 0, we don't know
                            isEssential = true;
                    }
                    if (isEssential && t2 instanceof LongType) {
                        Value v = expr.getOp2();
                        if (v instanceof LongConstant) {
                            LongConstant l = (LongConstant) v;
                            isEssential = (l.value == 0);
                        } else
                            // could be 0, we don't know
                            isEssential = true;
                    }
                }
            }
        }
        if (isEssential) {
            q.addFirst(s);
        }
        allEssential &= isEssential;
    }
    if (checkInvoke || !allEssential) {
        // Add all the statements which are used to compute values
        // for the essential statements, recursively
        final LocalDefs localDefs = LocalDefs.Factory.newLocalDefs(b);
        if (!allEssential) {
            Set<Unit> essential = new HashSet<Unit>(b.getUnits().size());
            while (!q.isEmpty()) {
                Unit s = q.removeFirst();
                if (essential.add(s)) {
                    for (ValueBox box : s.getUseBoxes()) {
                        Value v = box.getValue();
                        if (v instanceof Local) {
                            Local l = (Local) v;
                            List<Unit> defs = localDefs.getDefsOfAt(l, s);
                            if (defs != null)
                                q.addAll(defs);
                        }
                    }
                }
            }
            // Remove the dead statements
            units.retainAll(essential);
        }
        if (checkInvoke) {
            final LocalUses localUses = LocalUses.Factory.newLocalUses(b, localDefs);
            // Eliminate dead assignments from invokes such as x = f(), where
            // x is no longer used
            List<AssignStmt> postProcess = new ArrayList<AssignStmt>();
            for (Unit u : units) {
                if (u instanceof AssignStmt) {
                    AssignStmt s = (AssignStmt) u;
                    if (s.containsInvokeExpr()) {
                        // Just find one use of l which is essential
                        boolean deadAssignment = true;
                        for (UnitValueBoxPair pair : localUses.getUsesOf(s)) {
                            if (units.contains(pair.unit)) {
                                deadAssignment = false;
                                break;
                            }
                        }
                        if (deadAssignment) {
                            postProcess.add(s);
                        }
                    }
                }
            }
            final Jimple jimple = Jimple.v();
            for (AssignStmt s : postProcess) {
                // Transform it into a simple invoke.
                Stmt newInvoke = jimple.newInvokeStmt(s.getInvokeExpr());
                newInvoke.addAllTagsOf(s);
                units.swapWith(s, newInvoke);
                // If we have a callgraph, we need to fix it
                if (Scene.v().hasCallGraph())
                    Scene.v().getCallGraph().swapEdgesOutOf(s, newInvoke);
            }
        }
    }
    if (soptions.time()) {
        Timers.v().deadCodeTimer.end();
    }
}
Also used : Options(soot.options.Options) PhaseOptions(soot.PhaseOptions) LongType(soot.LongType) AssignStmt(soot.jimple.AssignStmt) NewMultiArrayExpr(soot.jimple.NewMultiArrayExpr) ArrayList(java.util.ArrayList) Unit(soot.Unit) IntType(soot.IntType) NopStmt(soot.jimple.NopStmt) AssignStmt(soot.jimple.AssignStmt) Stmt(soot.jimple.Stmt) RefType(soot.RefType) ArrayRef(soot.jimple.ArrayRef) InvokeExpr(soot.jimple.InvokeExpr) CastExpr(soot.jimple.CastExpr) InstanceFieldRef(soot.jimple.InstanceFieldRef) IntConstant(soot.jimple.IntConstant) UnitValueBoxPair(soot.toolkits.scalar.UnitValueBoxPair) HashSet(java.util.HashSet) LongConstant(soot.jimple.LongConstant) FieldRef(soot.jimple.FieldRef) InstanceFieldRef(soot.jimple.InstanceFieldRef) Local(soot.Local) NullConstant(soot.jimple.NullConstant) Trap(soot.Trap) LocalUses(soot.toolkits.scalar.LocalUses) LocalDefs(soot.toolkits.scalar.LocalDefs) ArrayDeque(java.util.ArrayDeque) UnknownType(soot.UnknownType) RefType(soot.RefType) Type(soot.Type) UnknownType(soot.UnknownType) IntType(soot.IntType) LongType(soot.LongType) NullType(soot.NullType) DivExpr(soot.jimple.DivExpr) NewArrayExpr(soot.jimple.NewArrayExpr) NopStmt(soot.jimple.NopStmt) RemExpr(soot.jimple.RemExpr) ValueBox(soot.ValueBox) Value(soot.Value) NewExpr(soot.jimple.NewExpr) Jimple(soot.jimple.Jimple) NullType(soot.NullType) BinopExpr(soot.jimple.BinopExpr)

Example 40 with Unit

use of soot.Unit in project soot by Sable.

the class NullCheckEliminator method internalTransform.

public void internalTransform(Body body, String phaseName, Map<String, String> options) {
    // really, the analysis should be able to use its own results to determine
    // that some branches are dead, but since it doesn't we just iterate.
    boolean changed;
    do {
        changed = false;
        NullnessAnalysis analysis = analysisFactory.newAnalysis(new ExceptionalUnitGraph(body));
        Chain<Unit> units = body.getUnits();
        Stmt s;
        for (s = (Stmt) units.getFirst(); s != null; s = (Stmt) units.getSuccOf(s)) {
            if (!(s instanceof IfStmt))
                continue;
            IfStmt is = (IfStmt) s;
            Value c = is.getCondition();
            if (!(c instanceof EqExpr || c instanceof NeExpr))
                continue;
            BinopExpr e = (BinopExpr) c;
            Immediate i = null;
            if (e.getOp1() instanceof NullConstant)
                i = (Immediate) e.getOp2();
            if (e.getOp2() instanceof NullConstant)
                i = (Immediate) e.getOp1();
            if (i == null)
                continue;
            boolean alwaysNull = analysis.isAlwaysNullBefore(s, i);
            boolean alwaysNonNull = analysis.isAlwaysNonNullBefore(s, i);
            // -1 => condition is false, 1 => condition is true
            int elim = 0;
            if (alwaysNonNull)
                elim = c instanceof EqExpr ? -1 : 1;
            if (alwaysNull)
                elim = c instanceof EqExpr ? 1 : -1;
            Stmt newstmt = null;
            if (elim == -1)
                newstmt = Jimple.v().newNopStmt();
            if (elim == 1)
                newstmt = Jimple.v().newGotoStmt(is.getTarget());
            if (newstmt != null) {
                units.swapWith(s, newstmt);
                s = newstmt;
                changed = true;
            }
        }
    } while (changed);
}
Also used : NeExpr(soot.jimple.NeExpr) Immediate(soot.Immediate) NullConstant(soot.jimple.NullConstant) Unit(soot.Unit) Stmt(soot.jimple.Stmt) IfStmt(soot.jimple.IfStmt) ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) IfStmt(soot.jimple.IfStmt) EqExpr(soot.jimple.EqExpr) Value(soot.Value) BinopExpr(soot.jimple.BinopExpr)

Aggregations

Unit (soot.Unit)240 Local (soot.Local)77 Stmt (soot.jimple.Stmt)77 Value (soot.Value)74 ArrayList (java.util.ArrayList)65 AssignStmt (soot.jimple.AssignStmt)58 SootMethod (soot.SootMethod)47 Body (soot.Body)37 InvokeStmt (soot.jimple.InvokeStmt)35 Type (soot.Type)34 HashSet (java.util.HashSet)33 ValueBox (soot.ValueBox)33 InvokeExpr (soot.jimple.InvokeExpr)33 Trap (soot.Trap)32 RefType (soot.RefType)30 IdentityStmt (soot.jimple.IdentityStmt)28 HashMap (java.util.HashMap)27 IfStmt (soot.jimple.IfStmt)27 DefinitionStmt (soot.jimple.DefinitionStmt)25 List (java.util.List)23