Search in sources :

Example 1 with CodeBlockRWSet

use of soot.jimple.toolkits.pointer.CodeBlockRWSet in project soot by Sable.

the class CriticalSectionInterferenceGraph method calculateGroups.

public void calculateGroups() {
    nextGroup = 1;
    groups = new ArrayList<CriticalSectionGroup>();
    // dummy group
    groups.add(new CriticalSectionGroup(0));
    if (// use one group for all transactions
    optionOneGlobalLock) {
        CriticalSectionGroup onlyGroup = new CriticalSectionGroup(nextGroup);
        Iterator<CriticalSection> tnIt1 = criticalSections.iterator();
        while (tnIt1.hasNext()) {
            CriticalSection tn1 = tnIt1.next();
            onlyGroup.add(tn1);
        }
        nextGroup++;
        groups.add(onlyGroup);
    } else // calculate separate groups for transactions
    {
        Iterator<CriticalSection> tnIt1 = criticalSections.iterator();
        while (tnIt1.hasNext()) {
            CriticalSection tn1 = tnIt1.next();
            // if this transaction has somehow already been marked for deletion
            if (tn1.setNumber == -1)
                continue;
            // if this transaction is empty
            if (tn1.read.size() == 0 && tn1.write.size() == 0 && !optionLeaveOriginalLocks) {
                // this transaction has no effect except on locals... we don't need it!
                // AKA delete the transactional region (but don't really so long as we are using
                tn1.setNumber = -1;
            // the synchronized keyword in our language... because java guarantees memory
            // barriers at certain points in synchronized blocks)
            } else {
                Iterator<CriticalSection> tnIt2 = criticalSections.iterator();
                while (tnIt2.hasNext()) {
                    CriticalSection tn2 = tnIt2.next();
                    // check if this transactional region is going to be deleted
                    if (tn2.setNumber == -1)
                        continue;
                    // check if these two transactions can't ever be in parallel
                    if (!mayHappenInParallel(tn1, tn2))
                        continue;
                    // check for RW or WW data dependencies.
                    // or, for optionLeaveOriginalLocks, check type compatibility
                    SootClass classOne = null;
                    SootClass classTwo = null;
                    boolean typeCompatible = false;
                    boolean emptyEdge = false;
                    if (tn1.origLock != null && tn2.origLock != null) {
                        // Check if edge is empty
                        if (tn1.origLock == null || tn2.origLock == null)
                            emptyEdge = true;
                        else if (!(tn1.origLock instanceof Local) || !(tn2.origLock instanceof Local))
                            emptyEdge = !tn1.origLock.equals(tn2.origLock);
                        else
                            emptyEdge = !pta.reachingObjects((Local) tn1.origLock).hasNonEmptyIntersection(pta.reachingObjects((Local) tn2.origLock));
                        // Check if types are compatible
                        RefLikeType typeOne = (RefLikeType) tn1.origLock.getType();
                        RefLikeType typeTwo = (RefLikeType) tn2.origLock.getType();
                        classOne = (typeOne instanceof RefType) ? ((RefType) typeOne).getSootClass() : null;
                        classTwo = (typeTwo instanceof RefType) ? ((RefType) typeTwo).getSootClass() : null;
                        if (classOne != null && classTwo != null) {
                            Hierarchy h = Scene.v().getActiveHierarchy();
                            if (classOne.isInterface()) {
                                if (classTwo.isInterface()) {
                                    typeCompatible = h.getSubinterfacesOfIncluding(classOne).contains(classTwo) || h.getSubinterfacesOfIncluding(classTwo).contains(classOne);
                                } else {
                                    typeCompatible = h.getImplementersOf(classOne).contains(classTwo);
                                }
                            } else {
                                if (classTwo.isInterface()) {
                                    typeCompatible = h.getImplementersOf(classTwo).contains(classOne);
                                } else {
                                    typeCompatible = (classOne != null && Scene.v().getActiveHierarchy().getSubclassesOfIncluding(classOne).contains(classTwo) || classTwo != null && Scene.v().getActiveHierarchy().getSubclassesOfIncluding(classTwo).contains(classOne));
                                }
                            }
                        }
                    }
                    if ((!optionLeaveOriginalLocks && (tn1.write.hasNonEmptyIntersection(tn2.write) || tn1.write.hasNonEmptyIntersection(tn2.read) || tn1.read.hasNonEmptyIntersection(tn2.write))) || (optionLeaveOriginalLocks && typeCompatible && (optionIncludeEmptyPossibleEdges || !emptyEdge))) {
                        // Determine the size of the intersection for GraphViz output
                        CodeBlockRWSet rw = null;
                        int size;
                        if (optionLeaveOriginalLocks) {
                            rw = new CodeBlockRWSet();
                            size = emptyEdge ? 0 : 1;
                        } else {
                            rw = tn1.write.intersection(tn2.write);
                            rw.union(tn1.write.intersection(tn2.read));
                            rw.union(tn1.read.intersection(tn2.write));
                            size = rw.size();
                        }
                        // Record this
                        tn1.edges.add(new CriticalSectionDataDependency(tn2, size, rw));
                        if (size > 0) {
                            // if tn1 already is in a group
                            if (tn1.setNumber > 0) {
                                // if tn2 is NOT already in a group
                                if (tn2.setNumber == 0) {
                                    tn1.group.add(tn2);
                                } else // if tn2 is already in a group
                                if (tn2.setNumber > 0) {
                                    if (// if they are equal, then they are already in the same group!
                                    tn1.setNumber != tn2.setNumber) {
                                        tn1.group.mergeGroups(tn2.group);
                                    }
                                }
                            } else // if tn1 is NOT already in a group
                            if (tn1.setNumber == 0) {
                                // if tn2 is NOT already in a group
                                if (tn2.setNumber == 0) {
                                    CriticalSectionGroup newGroup = new CriticalSectionGroup(nextGroup);
                                    newGroup.add(tn1);
                                    newGroup.add(tn2);
                                    groups.add(newGroup);
                                    nextGroup++;
                                } else // if tn2 is already in a group
                                if (tn2.setNumber > 0) {
                                    tn2.group.add(tn1);
                                }
                            }
                        }
                    }
                }
                // If, after comparing to all other transactions, we have no group:
                if (tn1.setNumber == 0) {
                    // delete transactional region
                    tn1.setNumber = -1;
                }
            }
        }
    }
}
Also used : Local(soot.Local) CodeBlockRWSet(soot.jimple.toolkits.pointer.CodeBlockRWSet) SootClass(soot.SootClass) RefLikeType(soot.RefLikeType) RefType(soot.RefType) Hierarchy(soot.Hierarchy)

Aggregations

Hierarchy (soot.Hierarchy)1 Local (soot.Local)1 RefLikeType (soot.RefLikeType)1 RefType (soot.RefType)1 SootClass (soot.SootClass)1 CodeBlockRWSet (soot.jimple.toolkits.pointer.CodeBlockRWSet)1