Search in sources :

Example 1 with EquivalentValue

use of soot.EquivalentValue in project soot by Sable.

the class DeadlockDetector method reorderLocksets.

public void reorderLocksets(Map<Value, Integer> lockToLockNum, MutableEdgeLabelledDirectedGraph<Integer, CriticalSection> lockOrder) {
    for (CriticalSection tn : criticalSections) {
        // Get the portion of the lock order that is visible to tn
        HashMutableDirectedGraph<Integer> visibleOrder = new HashMutableDirectedGraph<Integer>();
        if (tn.group != null) {
            for (CriticalSection otherTn : criticalSections) {
                // Check if otherTn and tn share a static lock
                boolean tnsShareAStaticLock = false;
                for (EquivalentValue tnLockEqVal : tn.lockset) {
                    Integer tnLockNum = lockToLockNum.get(tnLockEqVal.getValue());
                    if (tnLockNum < 0) {
                        // this is a static lock... see if some lock in labelTn has the same #
                        if (otherTn.group != null) {
                            for (EquivalentValue otherTnLockEqVal : otherTn.lockset) {
                                if (Objects.equals(lockToLockNum.get(otherTnLockEqVal.getValue()), tnLockNum)) {
                                    tnsShareAStaticLock = true;
                                }
                            }
                        } else {
                            // not really... but we want to skip this one
                            tnsShareAStaticLock = true;
                        }
                    }
                }
                if (// if tns don't share any static lock, or if tns are the same one
                !tnsShareAStaticLock || tn == otherTn) {
                    // add these orderings to tn's visible order
                    DirectedGraph<Integer> orderings = lockOrder.getEdgesForLabel(otherTn);
                    for (Integer node1 : orderings) {
                        if (!visibleOrder.containsNode(node1)) {
                            visibleOrder.addNode(node1);
                        }
                        for (Integer node2 : orderings.getSuccsOf(node1)) {
                            if (!visibleOrder.containsNode(node2)) {
                                visibleOrder.addNode(node2);
                            }
                            visibleOrder.addEdge(node1, node2);
                        }
                    }
                }
            }
            logger.debug("VISIBLE ORDER FOR " + tn.name);
            visibleOrder.printGraph();
            // Order locks in tn's lockset according to the visible order (insertion sort)
            List<EquivalentValue> newLockset = new ArrayList<EquivalentValue>();
            for (EquivalentValue lockEqVal : tn.lockset) {
                Value lockToInsert = lockEqVal.getValue();
                Integer lockNumToInsert = lockToLockNum.get(lockToInsert);
                int i = 0;
                while (i < newLockset.size()) {
                    EquivalentValue existingLockEqVal = newLockset.get(i);
                    Value existingLock = existingLockEqVal.getValue();
                    Integer existingLockNum = lockToLockNum.get(existingLock);
                    if (visibleOrder.containsEdge(lockNumToInsert, existingLockNum) || // !visibleOrder.containsEdge(existingLockNum, lockNumToInsert) ) // if(! existing before toinsert )
                    lockNumToInsert < existingLockNum) {
                        break;
                    }
                    i++;
                }
                newLockset.add(i, lockEqVal);
            }
            logger.debug("reordered from " + LockAllocator.locksetToLockNumString(tn.lockset, lockToLockNum) + " to " + LockAllocator.locksetToLockNumString(newLockset, lockToLockNum));
            tn.lockset = newLockset;
        }
    }
}
Also used : EquivalentValue(soot.EquivalentValue) ArrayList(java.util.ArrayList) EquivalentValue(soot.EquivalentValue) Value(soot.Value) HashMutableDirectedGraph(soot.toolkits.graph.HashMutableDirectedGraph)

Example 2 with EquivalentValue

use of soot.EquivalentValue in project soot by Sable.

the class LockAllocationBodyTransformer method getLockFor.

public static Value getLockFor(EquivalentValue lockEqVal) {
    Value lock = lockEqVal.getValue();
    if (lock instanceof InstanceFieldRef)
        return lock;
    if (// it would be better to lock the array
    lock instanceof ArrayRef)
        // ref for each value of the index!
        return ((ArrayRef) lock).getBase();
    if (lock instanceof Local)
        return lock;
    if (lock instanceof StaticFieldRef || lock instanceof NewStaticLock) {
        if (lockEqValToLock.containsKey(lockEqVal))
            return lockEqValToLock.get(lockEqVal);
        SootClass lockClass = null;
        if (lock instanceof StaticFieldRef) {
            StaticFieldRef sfrLock = (StaticFieldRef) lock;
            lockClass = sfrLock.getField().getDeclaringClass();
        } else if (lock instanceof NewStaticLock) {
            DeadlockAvoidanceEdge dae = (DeadlockAvoidanceEdge) lock;
            lockClass = dae.getLockClass();
        }
        SootMethod clinitMethod = null;
        JimpleBody clinitBody = null;
        Stmt firstStmt = null;
        boolean addingNewClinit = !lockClass.declaresMethod("void <clinit>()");
        if (addingNewClinit) {
            clinitMethod = Scene.v().makeSootMethod("<clinit>", new ArrayList(), VoidType.v(), Modifier.PUBLIC | Modifier.STATIC);
            clinitBody = Jimple.v().newBody(clinitMethod);
            clinitMethod.setActiveBody(clinitBody);
            lockClass.addMethod(clinitMethod);
        } else {
            clinitMethod = lockClass.getMethod("void <clinit>()");
            clinitBody = (JimpleBody) clinitMethod.getActiveBody();
            firstStmt = clinitBody.getFirstNonIdentityStmt();
        }
        PatchingChain<Unit> clinitUnits = clinitBody.getUnits();
        Local lockLocal = Jimple.v().newLocal("objectLockLocal" + lockNumber, RefType.v("java.lang.Object"));
        // lockNumber is increased below
        // TODO: add name conflict
        clinitBody.getLocals().add(lockLocal);
        // avoidance code
        // assign new object to lock obj
        Stmt newStmt = Jimple.v().newAssignStmt(lockLocal, Jimple.v().newNewExpr(RefType.v("java.lang.Object")));
        if (addingNewClinit)
            clinitUnits.add(newStmt);
        else
            clinitUnits.insertBeforeNoRedirect(newStmt, firstStmt);
        // initialize new object
        SootClass objectClass = Scene.v().loadClassAndSupport("java.lang.Object");
        RefType type = RefType.v(objectClass);
        SootMethod initMethod = objectClass.getMethod("void <init>()");
        Stmt initStmt = Jimple.v().newInvokeStmt(Jimple.v().newSpecialInvokeExpr(lockLocal, initMethod.makeRef(), Collections.EMPTY_LIST));
        if (addingNewClinit)
            clinitUnits.add(initStmt);
        else
            clinitUnits.insertBeforeNoRedirect(initStmt, firstStmt);
        // copy new object to global static lock object (for use by other
        // fns)
        SootField actualLockObject = Scene.v().makeSootField("objectLockGlobal" + lockNumber, RefType.v("java.lang.Object"), Modifier.STATIC | Modifier.PUBLIC);
        lockNumber++;
        lockClass.addField(actualLockObject);
        StaticFieldRef actualLockSfr = Jimple.v().newStaticFieldRef(actualLockObject.makeRef());
        Stmt assignStmt = Jimple.v().newAssignStmt(actualLockSfr, lockLocal);
        if (addingNewClinit)
            clinitUnits.add(assignStmt);
        else
            clinitUnits.insertBeforeNoRedirect(assignStmt, firstStmt);
        if (addingNewClinit)
            clinitUnits.add(Jimple.v().newReturnVoidStmt());
        lockEqValToLock.put(lockEqVal, actualLockSfr);
        return actualLockSfr;
    }
    throw new RuntimeException("Unknown type of lock (" + lock + "): expected FieldRef, ArrayRef, or Local");
}
Also used : ArrayList(java.util.ArrayList) FakeJimpleLocal(soot.jimple.toolkits.infoflow.FakeJimpleLocal) Local(soot.Local) SootClass(soot.SootClass) Unit(soot.Unit) StaticFieldRef(soot.jimple.StaticFieldRef) Stmt(soot.jimple.Stmt) ArrayRef(soot.jimple.ArrayRef) RefType(soot.RefType) EquivalentValue(soot.EquivalentValue) Value(soot.Value) InstanceFieldRef(soot.jimple.InstanceFieldRef) SootMethod(soot.SootMethod) SootField(soot.SootField) JimpleBody(soot.jimple.JimpleBody)

Example 3 with EquivalentValue

use of soot.EquivalentValue in project soot by Sable.

the class CachedEquivalentValue method equals.

public boolean equals(Object o) {
    if (this.getClass() != o.getClass()) {
        return false;
    }
    EquivalentValue ev = (EquivalentValue) o;
    Value v = ev.getValue();
    Boolean b = isEquivalent.get(v);
    if (b == null) {
        b = super.equals(o);
        isEquivalent.put(v, b);
    }
    return b;
}
Also used : EquivalentValue(soot.EquivalentValue) EquivalentValue(soot.EquivalentValue) Value(soot.Value)

Example 4 with EquivalentValue

use of soot.EquivalentValue in project soot by Sable.

the class LocalMustAliasAnalysis method numberOfRhs.

private Integer numberOfRhs(Value rhs) {
    EquivalentValue equivValue = new EquivalentValue(rhs);
    if (localsAndFieldRefs.contains(equivValue)) {
        rhs = equivValue;
    }
    Integer num = rhsToNumber.get(rhs);
    if (num == null) {
        num = nextNumber++;
        rhsToNumber.put(rhs, num);
    }
    return num;
}
Also used : EquivalentValue(soot.EquivalentValue)

Example 5 with EquivalentValue

use of soot.EquivalentValue in project soot by Sable.

the class LocalMustAliasAnalysis method trackableFields.

/**
 * Computes the set of {@link EquivalentValue}s of all field references that are used
 * in this method but not set by the method or any method transitively called by this method.
 */
private Set<Value> trackableFields() {
    Set<Value> usedFieldRefs = new HashSet<Value>();
    // add all field references that are in use boxes
    for (Unit unit : this.graph) {
        Stmt s = (Stmt) unit;
        List<ValueBox> useBoxes = s.getUseBoxes();
        for (ValueBox useBox : useBoxes) {
            Value val = useBox.getValue();
            if (val instanceof FieldRef) {
                FieldRef fieldRef = (FieldRef) val;
                if (fieldRef.getType() instanceof RefLikeType)
                    usedFieldRefs.add(new EquivalentValue(fieldRef));
            }
        }
    }
    // prune all fields that are written to
    if (!usedFieldRefs.isEmpty()) {
        if (!Scene.v().hasCallGraph()) {
            throw new IllegalStateException("No call graph found!");
        }
        CallGraph cg = Scene.v().getCallGraph();
        ReachableMethods reachableMethods = new ReachableMethods(cg, Collections.<MethodOrMethodContext>singletonList(container));
        reachableMethods.update();
        for (Iterator<MethodOrMethodContext> iterator = reachableMethods.listener(); iterator.hasNext(); ) {
            SootMethod m = (SootMethod) iterator.next();
            if (m.hasActiveBody() && // exclude static initializer of same class (assume that it has already been executed)
            !(m.getName().equals(SootMethod.staticInitializerName) && m.getDeclaringClass().equals(container.getDeclaringClass()))) {
                for (Unit u : m.getActiveBody().getUnits()) {
                    List<ValueBox> defBoxes = u.getDefBoxes();
                    for (ValueBox defBox : defBoxes) {
                        Value value = defBox.getValue();
                        if (value instanceof FieldRef) {
                            usedFieldRefs.remove(new EquivalentValue(value));
                        }
                    }
                }
            }
        }
    }
    return usedFieldRefs;
}
Also used : EquivalentValue(soot.EquivalentValue) FieldRef(soot.jimple.FieldRef) Unit(soot.Unit) Stmt(soot.jimple.Stmt) DefinitionStmt(soot.jimple.DefinitionStmt) RefLikeType(soot.RefLikeType) ReachableMethods(soot.jimple.toolkits.callgraph.ReachableMethods) CallGraph(soot.jimple.toolkits.callgraph.CallGraph) ValueBox(soot.ValueBox) EquivalentValue(soot.EquivalentValue) Value(soot.Value) SootMethod(soot.SootMethod) MethodOrMethodContext(soot.MethodOrMethodContext) HashSet(java.util.HashSet)

Aggregations

EquivalentValue (soot.EquivalentValue)11 Value (soot.Value)10 Local (soot.Local)6 Unit (soot.Unit)6 Stmt (soot.jimple.Stmt)6 ArrayList (java.util.ArrayList)5 SootMethod (soot.SootMethod)4 DefinitionStmt (soot.jimple.DefinitionStmt)3 FieldRef (soot.jimple.FieldRef)3 InstanceFieldRef (soot.jimple.InstanceFieldRef)3 FakeJimpleLocal (soot.jimple.toolkits.infoflow.FakeJimpleLocal)3 MethodOrMethodContext (soot.MethodOrMethodContext)2 RefLikeType (soot.RefLikeType)2 RefType (soot.RefType)2 SootClass (soot.SootClass)2 SootField (soot.SootField)2 ArrayRef (soot.jimple.ArrayRef)2 JimpleBody (soot.jimple.JimpleBody)2 StaticFieldRef (soot.jimple.StaticFieldRef)2 Pair (soot.toolkits.scalar.Pair)2