use of soot.Hierarchy 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;
}
}
}
}
}
use of soot.Hierarchy in project soot by Sable.
the class JavaTranslator method translateApplicationClasses.
public Method[] translateApplicationClasses() {
h = new Hierarchy();
makeMethods();
translate();
return methods.toArray(new Method[0]);
}
use of soot.Hierarchy in project soot by Sable.
the class HeapInsNode method do_before_propagation.
@Override
public void do_before_propagation() {
// if ( complex_cons == null )
do_pts_interval_merge();
// if ( !(me instanceof LocalVarNode) )
do_flow_edge_interval_merge();
// This pointer filter, please read the comments at this line in file FullSensitiveNode.java
Node wrappedNode = getWrappedNode();
if (wrappedNode instanceof LocalVarNode && ((LocalVarNode) wrappedNode).isThisPtr()) {
SootMethod func = ((LocalVarNode) wrappedNode).getMethod();
if (!func.isConstructor()) {
// We don't process the specialinvoke call edge
SootClass defClass = func.getDeclaringClass();
Hierarchy typeHierarchy = Scene.v().getActiveHierarchy();
for (Iterator<AllocNode> it = new_pts.keySet().iterator(); it.hasNext(); ) {
AllocNode obj = it.next();
if (obj.getType() instanceof RefType) {
SootClass sc = ((RefType) obj.getType()).getSootClass();
if (defClass != sc) {
try {
SootMethod rt_func = typeHierarchy.resolveConcreteDispatch(sc, func);
if (rt_func != func) {
it.remove();
// Also preclude it from propagation again
pt_objs.put(obj, (HeapInsIntervalManager) deadManager);
}
} catch (RuntimeException e) {
// If the input program has a wrong type cast, resolveConcreteDispatch fails and it goes here
// We simply ignore this error
}
}
}
}
}
}
}
use of soot.Hierarchy in project soot by Sable.
the class PtInsNode method do_before_propagation.
@Override
public void do_before_propagation() {
// if ( complex_cons == null )
do_pts_interval_merge();
// if ( !(me instanceof LocalVarNode) )
do_flow_edge_interval_merge();
// This pointer filter, please read the comments at this line in file FullSensitiveNode.java
Node wrappedNode = getWrappedNode();
if (wrappedNode instanceof LocalVarNode && ((LocalVarNode) wrappedNode).isThisPtr()) {
SootMethod func = ((LocalVarNode) wrappedNode).getMethod();
if (!func.isConstructor()) {
// We don't process the specialinvoke call edge
SootClass defClass = func.getDeclaringClass();
Hierarchy typeHierarchy = Scene.v().getActiveHierarchy();
for (Iterator<AllocNode> it = new_pts.keySet().iterator(); it.hasNext(); ) {
AllocNode obj = it.next();
if (obj.getType() instanceof RefType) {
SootClass sc = ((RefType) obj.getType()).getSootClass();
if (defClass != sc) {
try {
SootMethod rt_func = typeHierarchy.resolveConcreteDispatch(sc, func);
if (rt_func != func) {
it.remove();
// Also preclude it from propagation again
pt_objs.put(obj, (PtInsIntervalManager) deadManager);
}
} catch (RuntimeException e) {
// If the input program has a wrong type cast, resolveConcreteDispatch fails and it goes here
// We simply ignore this error
}
}
}
}
}
}
}
use of soot.Hierarchy in project soot by Sable.
the class FullSensitiveNode method do_before_propagation.
@Override
public void do_before_propagation() {
// We first perform the geometric merging
do_pts_interval_merge();
do_flow_edge_interval_merge();
/*
* The following code eliminates the spurious points-to relation for THIS pointer.
* For example we have two classes A and B, B is a child class of A.
* We have a virtual function foo defined in both A and B.
* We have a pointer p in type A.
* pts(p) = { o1, o2 }, where o1 is in type A and o2 is in type B.
* Therefore, the call p.foo() will be resolved to call both A::foo and B::foo.
* Then, in the points-to analysis, we have two assignments: p -> A::foo.THIS, p -> B::foo.THIS
* At this time, obviously, although with the type filter, A::foo.THIS will receive the object o2, which is definitely a fake.
* Thus, we need a new filter to guarantee that A::foo.THIS only points to o1.
* We call this filter "this pointer filter".
*/
Node wrappedNode = getWrappedNode();
if (wrappedNode instanceof LocalVarNode && ((LocalVarNode) wrappedNode).isThisPtr()) {
SootMethod func = ((LocalVarNode) wrappedNode).getMethod();
if (!func.isConstructor()) {
// We don't process the specialinvoke call edge
SootClass defClass = func.getDeclaringClass();
Hierarchy typeHierarchy = Scene.v().getActiveHierarchy();
for (Iterator<AllocNode> it = new_pts.keySet().iterator(); it.hasNext(); ) {
AllocNode obj = it.next();
if (obj.getType() instanceof RefType) {
SootClass sc = ((RefType) obj.getType()).getSootClass();
if (defClass != sc) {
try {
SootMethod rt_func = typeHierarchy.resolveConcreteDispatch(sc, func);
if (rt_func != func) {
it.remove();
// Also preclude it from propagation again
pt_objs.put(obj, (GeometricManager) deadManager);
}
} catch (RuntimeException e) {
// If the input program has a wrong type cast, resolveConcreteDispatch fails and it goes here
// We simply ignore this error
}
}
}
}
}
}
}
Aggregations