return out;
}
+ // BOO, HISS! SESE (rblock) operand does NOT extend
+ // Canonical, so we can't cache this op by its
+ // canonical arguments--THINK ABOUT A BETTER WAY!
+ public static TaintSet removeSESETaints( TaintSet ts,
+ Set<FlatSESEEnterNode> seseSet ) {
+ assert ts != null;
+ assert ts.isCanonical();
+
+ // NEVER a cached result... (cry)
+ TaintSet out = new TaintSet();
+
+ Iterator<Taint> tItr = ts.iterator();
+ while( tItr.hasNext() ) {
+ Taint t = tItr.next();
+
+ // what is allowed through? stall site taints always
+ // go through, anything where rblock doesn't match is
+ // unaffected, and if the taint has a non-empty predicate
+ // it is out of context so it should go through, too
+ if( t.getSESE() == null ||
+ seseSet.contains(t)) {
+ out.taints.add( t );
+ }
+ }
+
+ out = (TaintSet) makeCanonical( out );
+ //op2result.put( op, out ); CRY CRY
+ return out;
+ }
+
public static TaintSet removeInContextTaintsNP( TaintSet ts,
FlatSESEEnterNode sese ) {
assert ts != null;
// node it will be in this set
protected Hashtable< FlatNode, Set<FlatSESEEnterNode> > fn2currentSESEs;
+ // if you want to know which rblocks might be executing a given flat
+ // node it will be in this set
+ protected Hashtable< FlatNode, Set<FlatSESEEnterNode> > fn2allSESEs;
+
// if you want to know the method-local, inner-most nested task that
// is executing a flat node, it is either here or null.
//
return out;
}
+ /* Returns all SESE's that this fn can be a member of
+ * transitively. */
+
+ public Set<FlatSESEEnterNode> getTransitiveExecutingRBlocks(FlatNode fn) {
+ if (fn2allSESEs.containsKey(fn))
+ return fn2allSESEs.get(fn);
+
+ //Compute and memoize result
+ HashSet<FlatSESEEnterNode> seseSet=new HashSet<FlatSESEEnterNode>();
+ fn2allSESEs.put(fn, seseSet);
+ Stack<FlatNode> toprocess=new Stack<FlatNode>();
+ toprocess.add(fn);
+ while(!toprocess.isEmpty()) {
+ FlatNode curr=toprocess.pop();
+ Set<FlatSESEEnterNode> callers=fn2currentSESEs.get(curr);
+ if (callers!=null) {
+ for(FlatSESEEnterNode sese:callers) {
+ if (!seseSet.contains(sese)) {
+ seseSet.add(sese);
+ toprocess.add(fn);
+ }
+ }
+ }
+ }
+ return seseSet;
+ }
+
public Set<FlatSESEEnterNode> getPossibleExecutingRBlocks( FlatNode fn ) {
Set<FlatSESEEnterNode> out = fn2currentSESEs.get( fn );
if( out == null ) {
fn2currentSESEs = new Hashtable<FlatNode, Set<FlatSESEEnterNode>>();
fn2localInnerSESE = new Hashtable<FlatNode, FlatSESEEnterNode>();
fn2isPotentialStallSite = new Hashtable<FlatNode, Boolean>();
+ fn2allSESEs = new Hashtable< FlatNode, Set<FlatSESEEnterNode>>();
MethodDescriptor mdSourceEntry = typeUtil.getMain();
return hasChildrenByCall;
}
-
-
protected void findPossibleExecutingRBlocksAndStallSites() {
for( Iterator<FlatSESEEnterNode> fsenItr = allSESEs.iterator(); fsenItr.hasNext(); ) {
FlatSESEEnterNode fsen = fsenItr.next();
// your own exit, because one instance can
// recursively invoke another
addPossibleExecutingRBlock( child.getFlatExit(), fsen );
-
+
continue;
}
import IR.Flat.*;
import IR.*;
import Analysis.Pointer.AllocFactory.AllocNode;
+import Analysis.Disjoint.Canonical;
import Analysis.Disjoint.Taint;
import Analysis.Disjoint.TaintSet;
import Analysis.Pointer.MySet;
+import java.util.*;
public class Edge {
FieldDescriptor fd;
return newe;
}
+ public void taintModify(Set<FlatSESEEnterNode> seseSet) {
+ if (taints!=null)
+ taints=Canonical.removeSESETaints(taints, seseSet);
+ }
+
public TaintSet getTaints() {
return taints;
}
public Edge changeSrcVar(TempDescriptor tmp, TaintSet taintset) {
Edge e=new Edge();
e.fd=fd;
- e.srcvar=srcvar;
+ e.srcvar=tmp;
e.dst=dst;
e.statuspredicate=NEW;
if (taints==null)
return e;
}
- public boolean statusDominates(Edge other) {
- return (statuspredicate==NEW)||
- ((other.statuspredicate|statuspredicate)==statuspredicate);
- }
-
public Edge makeStatus(AllocFactory factory) {
Edge e=new Edge();
e.fd=fd;
}
public boolean subsumes(Edge e) {
- return subsumes(this.statuspredicate, e.statuspredicate);
+ return subsumes(this.statuspredicate, e.statuspredicate)&&subsumes(this.taints, e.taints);
+ }
+
+ public static boolean subsumes(TaintSet ts1, TaintSet ts2) {
+ if (ts2==null)
+ return true;
+ if (ts1==null) {
+ if (ts2.isEmpty())
+ return true;
+ else
+ return false;
+ }
+ //Neither is null
+ //Do a set comparison
+
+ return ts1.getTaints().containsAll(ts2.getTaints());
}
public static boolean subsumes(int status1, int status2) {
Graph oldgraph=(ppoint.getIndex()==0)?
bbgraphMap.get(bblock):
graphMap.get(nodes.get(ppoint.getIndex()-1));
+ Set<FlatSESEEnterNode> seseCallers=OoOJava?taskAnalysis.getTransitiveExecutingRBlocks(fcall):null;
//Age outside nodes if necessary
for(Iterator<AllocNode> nodeit=delta.addNodeAges.iterator();nodeit.hasNext();) {
edgetoadd=origEdgeKey;
}
}
+ if (seseCallers!=null)
+ edgetoadd.taintModify(seseCallers);
mergeCallEdge(graph, newDelta, edgetoadd);
}
}
for(Edge e:returnedge) {
Edge newedge=e.copy();
newedge.srcvar=fcall.getReturnTemp();
+ if (seseCallers!=null)
+ newedge.taintModify(seseCallers);
if (graph.getEdges(fcall.getReturnTemp())==null||!graph.getEdges(fcall.getReturnTemp()).contains(newedge))
newDelta.addEdge(newedge);
}