X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=Robust%2Fsrc%2FAnalysis%2FPointer%2FPointer.java;h=f1fddad9884416a17c175dbae0befdf46445e5e3;hb=6c22cffed94206645d16712e7a5b615d8a94f7e9;hp=a801f12d97afad93f26ebbf0444efdb1c765774a;hpb=986c8afba41ed5565f65b1e3ea15233d0dafc910;p=IRC.git diff --git a/Robust/src/Analysis/Pointer/Pointer.java b/Robust/src/Analysis/Pointer/Pointer.java index a801f12d..f1fddad9 100644 --- a/Robust/src/Analysis/Pointer/Pointer.java +++ b/Robust/src/Analysis/Pointer/Pointer.java @@ -5,21 +5,53 @@ import IR.*; import Analysis.Liveness; import Analysis.Pointer.BasicBlock.BBlock; import Analysis.Pointer.AllocFactory.AllocNode; +import Analysis.Disjoint.Alloc; +import Analysis.Disjoint.Taint; +import Analysis.Disjoint.TaintSet; +import Analysis.Disjoint.Canonical; +import Analysis.Disjoint.HeapAnalysis; +import Analysis.CallGraph.CallGraph; +import Analysis.OoOJava.RBlockRelationAnalysis; +import Analysis.OoOJava.Accessible; +import Analysis.Disjoint.ExistPred; +import Analysis.Disjoint.ReachGraph; +import Analysis.Disjoint.EffectsAnalysis; +import Analysis.Disjoint.BuildStateMachines; import java.io.*; -public class Pointer { + +public class Pointer implements HeapAnalysis{ HashMap blockMap; HashMap bbgraphMap; HashMap graphMap; HashMap> callMap; HashMap> returnMap; HashMap> bblivetemps; + HashSet mustProcess; + private boolean OoOJava=false; + CallGraph callGraph; State state; TypeUtil typeUtil; AllocFactory allocFactory; LinkedList toprocess; TempDescriptor returntmp; + RBlockRelationAnalysis taskAnalysis; + EffectsAnalysis effectsAnalysis; + Accessible accessible; + + public Pointer(State state, TypeUtil typeUtil, CallGraph callGraph, RBlockRelationAnalysis taskAnalysis, Liveness liveness, BuildStateMachines bsm) { + this(state, typeUtil); + this.callGraph=callGraph; + this.OoOJava=true; + this.taskAnalysis=taskAnalysis; + this.effectsAnalysis=new EffectsAnalysis(); + effectsAnalysis.state=state; + effectsAnalysis.buildStateMachines=bsm; + accessible=new Accessible(state, callGraph, taskAnalysis, liveness); + accessible.doAnalysis(); + State.logEvent("Done Writing Accessible Analysis"); + } public Pointer(State state, TypeUtil typeUtil) { this.state=state; @@ -34,6 +66,11 @@ public class Pointer { this.toprocess=new LinkedList(); ClassDescriptor stringcd=typeUtil.getClass(TypeUtil.ObjectClass); this.returntmp=new TempDescriptor("RETURNVAL", stringcd); + this.mustProcess=new HashSet(); + } + + public EffectsAnalysis getEffectsAnalysis() { + return effectsAnalysis; } public BasicBlock getBBlock(FlatMethod fm) { @@ -72,7 +109,13 @@ public class Pointer { return delta; } + + public Graph getGraph(FlatNode fn) { + return graphMap.get(fn); + } + public void doAnalysis() { + toprocess.add(buildInitialContext()); nextdelta: while(!toprocess.isEmpty()) { @@ -104,13 +147,44 @@ public class Pointer { if (!init&&delta.isEmpty()) continue nextdelta; + int lasti=-1; //Compute delta at exit of each node for(int i=startindex; i=i;lasti--) { + FlatNode scurrNode=nodes.get(lasti); + if (isNEEDED(scurrNode)||isINACC(scurrNode)) { + break; + } + } + } + if (i==lasti) { + mustProcess.add(currNode); + graphMap.put(currNode, new Graph(graph)); + fallthru=false; + } + } + if (fallthru) { + if (i==0) { + //base graph works for us + graphMap.put(currNode, new Graph(graph)); + } else { + //just use previous graph + graphMap.put(currNode, graphMap.get(nodes.get(i-1))); + } + } + } } + nodeGraph=graphMap.get(currNode); delta=processNode(bblock, i, currNode, delta, nodeGraph); //System.out.println("Processing "+currNode+" and generating delta:"); @@ -120,13 +194,14 @@ public class Pointer { } //DEBUG - if (true) { + if (false) { int debugindex=0; for(Map.Entry e:bbgraphMap.entrySet()) { Graph g=e.getValue(); plotGraph(g,"BB"+e.getKey().nodes.get(0).toString().replace(' ','_')); debugindex++; } + for(FlatMethod fm:blockMap.keySet()) { System.out.println(fm.printMethod()); } @@ -137,6 +212,14 @@ public class Pointer { debugindex++; } } + + State.logEvent("Done With Pointer Analysis"); + + + if (OoOJava) { + effectsAnalysis.buildStateMachines.writeStateMachines(); + State.logEvent("Done Writing State Machines"); + } } void plotGraph(Graph g, String name) { @@ -185,12 +268,6 @@ public class Pointer { edgeSet.addAll(graph.parent.nodeMap.get(node)); newDelta.heapedgeadd.put(node, edgeSet); - /* Compute ages */ - if (graph.nodeAges.contains(node)) - newDelta.addNodeAges.add(node); - else if (graph.parent.nodeAges.contains(node)) - newDelta.addNodeAges.add(node); - /* Compute ages */ if (graph.oldNodes.containsKey(node)) { if (graph.oldNodes.get(node).booleanValue()) @@ -200,6 +277,9 @@ public class Pointer { newDelta.addOldNodes.put(node, Boolean.TRUE); } } + + newDelta.addNodeAges.addAll(graph.nodeAges); + newDelta.addNodeAges.addAll(graph.parent.nodeAges); } /* This function build the delta for the exit of a basic block. */ @@ -319,6 +399,28 @@ public class Pointer { } } + boolean isNEEDED(FlatNode node) { + switch(node.kind()) { + case FKind.FlatSetFieldNode: { + FlatSetFieldNode n=(FlatSetFieldNode)node; + return n.getSrc().getType().isPtr(); + } + case FKind.FlatSetElementNode: { + FlatSetElementNode n=(FlatSetElementNode)node; + return n.getSrc().getType().isPtr(); + } + case FKind.FlatFieldNode: { + FlatFieldNode n=(FlatFieldNode)node; + return n.getDst().getType().isPtr(); + } + case FKind.FlatElementNode: { + FlatElementNode n=(FlatElementNode)node; + return n.getDst().getType().isPtr(); + } + } + return true; + } + Delta processNode(BBlock bblock, int index, FlatNode node, Delta delta, Graph newgraph) { switch(node.kind()) { case FKind.FlatNew: @@ -333,12 +435,14 @@ public class Pointer { case FKind.FlatSetFieldNode: case FKind.FlatSetElementNode: return processSetFieldElementNode(node, delta, newgraph); + case FKind.FlatSESEEnterNode: + return processSESEEnterNode((FlatSESEEnterNode) node, delta, newgraph); + case FKind.FlatSESEExitNode: + return processSESEExitNode((FlatSESEExitNode) node, delta, newgraph); case FKind.FlatMethod: case FKind.FlatExit: case FKind.FlatBackEdge: case FKind.FlatGenReachNode: - case FKind.FlatSESEEnterNode: - case FKind.FlatSESEExitNode: return processFlatNop(node, delta, newgraph); case FKind.FlatCall: return processFlatCall(bblock, index, (FlatCall) node, delta, newgraph); @@ -347,6 +451,156 @@ public class Pointer { } } + Delta processSESEEnterNode(FlatSESEEnterNode sese, Delta delta, Graph graph) { + if (!OoOJava) + return processFlatNop(sese, delta, graph); + if (delta.getInit()) { + removeInitTaints(null, delta, graph); + for (TempDescriptor tmp:sese.getInVarSet()) { + Taint taint=Taint.factory(sese, null, tmp, AllocFactory.dummySite, null, ReachGraph.predsEmpty); + MySet edges=GraphManip.getEdges(graph, delta, tmp); + for(Edge e:edges) { + Edge newe=e.addTaint(taint); + delta.addVarEdge(newe); + } + } + } else { + removeDiffTaints(null, delta); + for (TempDescriptor tmp:sese.getInVarSet()) { + Taint taint=Taint.factory(sese, null, tmp, AllocFactory.dummySite, null, ReachGraph.predsEmpty); + MySet edges=GraphManip.getDiffEdges(delta, tmp); + for(Edge e:edges) { + Edge newe=e.addTaint(taint); + delta.addVarEdge(newe); + } + } + } + + + applyDiffs(graph, delta); + return delta; + } + + private boolean isRecursive(FlatSESEEnterNode sese) { + MethodDescriptor md=sese.getmdEnclosing(); + boolean isrecursive=callGraph.getCalleeSet(md).contains(md); + return isrecursive; + } + + Delta processSESEExitNode(FlatSESEExitNode seseexit, Delta delta, Graph graph) { + if (!OoOJava) + return processFlatNop(seseexit, delta, graph); + FlatSESEEnterNode sese=seseexit.getFlatEnter(); + //Strip Taints from this SESE + if (delta.getInit()) { + removeInitTaints(isRecursive(sese)?null:sese, delta, graph); + } else { + removeDiffTaints(isRecursive(sese)?null:sese, delta); + } + applyDiffs(graph, delta); + return delta; + } + + void removeDiffTaints(FlatSESEEnterNode sese, Delta delta) { + //Start with variable edges + { + MySet edgestoadd=new MySet(); + MySet edgestoremove=new MySet(); + + //Process base diff edges + processEdgeMap(sese, delta.basevaredge, null, delta.varedgeremove, edgestoremove, edgestoadd); + //Process delta edges + processEdgeMap(sese, delta.varedgeadd, null, null, edgestoremove, edgestoadd); + for(Edge e:edgestoremove) { + delta.removeVarEdge(e); + } + for(Edge e:edgestoadd) { + delta.addVarEdge(e); + } + } + + //Now do heap edges + { + MySet edgestoadd=new MySet(); + MySet edgestoremove=new MySet(); + + //Process base diff edges + processEdgeMap(sese, delta.baseheapedge, null, delta.heapedgeremove, edgestoremove, edgestoadd); + //Process delta edges + processEdgeMap(sese, delta.heapedgeadd, null, null, edgestoremove, edgestoadd); + for(Edge e:edgestoremove) { + delta.removeHeapEdge(e); + } + for(Edge e:edgestoadd) { + delta.addHeapEdge(e); + } + } + } + + void removeInitTaints(FlatSESEEnterNode sese, Delta delta, Graph graph) { + //Start with variable edges + { + MySet edgestoadd=new MySet(); + MySet edgestoremove=new MySet(); + + //Process parent edges + processEdgeMap(sese, graph.parent.varMap, graph.varMap, delta.varedgeremove, edgestoremove, edgestoadd); + //Process graph edges + processEdgeMap(sese, graph.varMap, null, delta.varedgeremove, edgestoremove, edgestoadd); + //Process delta edges + processEdgeMap(sese, delta.varedgeadd, null, null, edgestoremove, edgestoadd); + for(Edge e:edgestoremove) { + delta.removeVarEdge(e); + } + for(Edge e:edgestoadd) { + delta.addVarEdge(e); + } + } + + //Now do heap edges + { + MySet edgestoadd=new MySet(); + MySet edgestoremove=new MySet(); + + //Process parent edges + processEdgeMap(sese, graph.parent.nodeMap, graph.nodeMap, delta.heapedgeremove, edgestoremove, edgestoadd); + //Process graph edges + processEdgeMap(sese, graph.nodeMap, null, delta.heapedgeremove, edgestoremove, edgestoadd); + //Process delta edges + processEdgeMap(sese, delta.heapedgeadd, null, null, edgestoremove, edgestoadd); + for(Edge e:edgestoremove) { + delta.removeHeapEdge(e); + } + for(Edge e:edgestoadd) { + delta.addHeapEdge(e); + } + } + } + + void processEdgeMap(FlatSESEEnterNode sese, HashMap> edgemap, HashMap> childmap, HashMap> removemap, MySet edgestoremove, MySet edgestoadd) { + for(Map.Entry> entry:edgemap.entrySet()) { + //If the parent map exists and overrides this entry, skip it + if (childmap!=null&&childmap.containsKey(entry.getKey())) + continue; + for(Edge e:entry.getValue()) { + //check whether this edge has been removed + if (removemap!=null&&removemap.containsKey(entry.getKey())&& + removemap.get(entry.getKey()).contains(e)) + continue; + //have real edge + TaintSet ts=e.getTaints(); + TaintSet newts=null; + //update non-null taint set + if (ts!=null) + newts=Canonical.removeInContextTaintsNP(ts, sese); + if (newts!=null) { + edgestoremove.add(e); + edgestoadd.add(e.changeTaintSet(newts)); + } + } + } + } + /* This function compute the edges for the this variable for a * callee if it exists. */ @@ -398,7 +652,7 @@ public class Pointer { AllocNode node=tovisit.pop(); MySet edges=GraphManip.getEdges(graph, delta, node); if (!edges.isEmpty()) { - newDelta.heapedgeadd.put(node, edges); + newDelta.heapedgeadd.put(node, Edge.makeOld(edges)); edgeset.addAll(edges); for(Edge e:edges) { if (!nodeset.contains(e.dst)&&(oldnodeset==null||!oldnodeset.contains(e.dst))) { @@ -414,7 +668,7 @@ public class Pointer { TempDescriptor tmpthis=fcall.getThis(); MethodDescriptor md=fcall.getMethod(); HashSet targets=new HashSet(); - if (md.isStatic()) { + if (md.isStatic()||fcall.getSuper()) { targets.add(md); } else { //Compute Edges @@ -513,7 +767,8 @@ public class Pointer { } - /* This function computes all edges that start outside of the callee context and go into the callee context */ + /* This function computes all edges that start outside of the callee + * context and go into the callee context */ void computeExternalEdges(Graph graph, Delta delta, HashSet nodeset, HashSet deltaset, MySet externaledgeset) { //Do heap edges first @@ -535,7 +790,7 @@ public class Pointer { } } - //Do heap edges first + //Do var edges now HashSet temps=new HashSet(); temps.addAll(delta.basevaredge.keySet()); temps.addAll(delta.varedgeadd.keySet()); @@ -560,10 +815,10 @@ public class Pointer { /* This function removes the caller reachable edges from the * callee's heap. */ - void removeEdges(Delta delta, HashSet nodeset, MySet edgeset, MySet externaledgeset) { + void removeEdges(Graph graph, Delta delta, HashSet nodeset, MySet edgeset, MySet externaledgeset) { //Want to remove the set of internal edges for(Edge e:edgeset) { - if (e.src!=null) { + if (e.src!=null&&!graph.callerEdges.contains(e)) { delta.removeHeapEdge(e); } } @@ -571,7 +826,8 @@ public class Pointer { //Want to remove the set of external edges for(Edge e:externaledgeset) { //want to remove the set of internal edges - delta.removeEdge(e); + if (!graph.callerEdges.contains(e)) + delta.removeEdge(e); } } @@ -585,6 +841,7 @@ public class Pointer { HashSet targetSet=new HashSet(); Stack tovisit=new Stack(); TempDescriptor tmpthis=fcall.getThis(); + graph.callerEdges=new MySet(); //Handle the this temp processThisTargets(targetSet, graph, delta, newDelta, nodeset, tovisit, edgeset, tmpthis, null); @@ -605,7 +862,7 @@ public class Pointer { computeExternalEdges(graph, delta, nodeset, null, externaledgeset); //Splice out internal edges - removeEdges(delta, nodeset, edgeset, externaledgeset); + removeEdges(graph, delta, nodeset, edgeset, externaledgeset); //store data structures graph.externalEdgeSet=externaledgeset; @@ -615,6 +872,8 @@ public class Pointer { graph.callTargets=newtargets; graph.callNodeAges=new HashSet(); graph.callOldNodes=new HashSet(); + graph.callNewEdges=new HashMap>(); + graph.callOldEdges=new HashMap>(); //Apply diffs to graph applyDiffs(graph, delta, true); @@ -628,7 +887,24 @@ public class Pointer { HashSet targetSet=new HashSet(); Stack tovisit=new Stack(); TempDescriptor tmpthis=fcall.getThis(); + //Fix up delta to get rid of unnecessary heap edge removals + for(Map.Entry> entry:delta.heapedgeremove.entrySet()) { + for(Iterator eit=entry.getValue().iterator();eit.hasNext();) { + Edge e=eit.next(); + if (graph.callerEdges.contains(e)) + eit.remove(); + } + } + //Fix up delta to get rid of unnecessary var edge removals + for(Map.Entry> entry:delta.varedgeremove.entrySet()) { + for(Iterator eit=entry.getValue().iterator();eit.hasNext();) { + Edge e=eit.next(); + if (graph.callerEdges.contains(e)) + eit.remove(); + } + } + //Handle the this temp processThisTargets(targetSet, graph, delta, newDelta, nodeset, tovisit, edgeset, tmpthis, oldnodeset); @@ -643,7 +919,7 @@ public class Pointer { if (!newDelta.heapedgeadd.containsKey(src)) { newDelta.heapedgeadd.put(src, new MySet()); } - newDelta.heapedgeadd.get(src).add(e); + newDelta.heapedgeadd.get(src).add(e.makeOld()); if (!nodeset.contains(e.dst)&&!oldnodeset.contains(e.dst)) { nodeset.add(e.dst); tovisit.add(e.dst); @@ -655,6 +931,7 @@ public class Pointer { //Compute call targets HashSet newtargets=computeTargets(fcall, newDelta); graph.callTargets.addAll(newtargets); + //add in new nodeset and edgeset oldnodeset.addAll(nodeset); oldedgeset.addAll(edgeset); @@ -662,8 +939,45 @@ public class Pointer { fixMapping(fcall, graph.callTargets, oldedgeset, newDelta, callblock, callindex); //Compute edges into region to splice out computeExternalEdges(graph, delta, oldnodeset, nodeset, externaledgeset); + //Splice out internal edges - removeEdges(delta, nodeset, edgeset, externaledgeset); + removeEdges(graph, delta, nodeset, edgeset, externaledgeset); + + //Add external edges back in + processCallExternal(graph, delta, externaledgeset); + + //Move new edges that should be summarized + processSummarization(graph, delta); + + Set seseCallers=OoOJava?taskAnalysis.getTransitiveExecutingRBlocks(fcall):null; + //Check if the new nodes allow us to insert a new edge + for(AllocNode node:nodeset) { + if (graph.callNewEdges.containsKey(node)) { + for(Iterator eit=graph.callNewEdges.get(node).iterator();eit.hasNext();) { + Edge e=eit.next(); + if ((graph.callNodeAges.contains(e.src)||graph.reachNode.contains(e.src))&& + (graph.callNodeAges.contains(e.dst)||graph.reachNode.contains(e.dst))) { + Edge edgetoadd=e.copy();//we need our own copy to modify below + eit.remove(); + if (seseCallers!=null) + edgetoadd.taintModify(seseCallers); + mergeCallEdge(graph, delta, edgetoadd); + } + } + } + } + + for(Edge e:edgeset) { + //See if these edges would allow an old edge to be added + if (graph.callOldEdges.containsKey(e)) { + for(Edge adde:graph.callOldEdges.get(e)) { + Edge ecopy=adde.copy(); + ecopy.statuspredicate=e.statuspredicate; + mergeCallEdge(graph, delta, ecopy); + } + } + } + //Add in new external edges graph.externalEdgeSet.addAll(externaledgeset); //Apply diffs to graph @@ -672,6 +986,107 @@ public class Pointer { return delta; } + void processSummarization(Graph graph, Delta delta) { + processSumHeapEdgeSet(delta.heapedgeadd, delta, graph); + processSumHeapEdgeSet(delta.baseheapedge, delta, graph); + processSumVarEdgeSet(delta.varedgeadd, delta, graph); + processSumVarEdgeSet(delta.basevaredge, delta, graph); + } + + void processSumVarEdgeSet(HashMap> map, Delta delta, Graph graph) { + MySet edgestoadd=new MySet(); + MySet edgestoremove=new MySet(); + for(Iterator>> eit=map.entrySet().iterator();eit.hasNext();) { + Map.Entry> entry=eit.next(); + MySet edgeset=entry.getValue(); + + for(Edge e:edgeset) { + Edge copy=e.copy(); + boolean rewrite=false; + if (copy.dst!=null&&graph.callNodeAges.contains(copy.dst)) { + copy.dst=allocFactory.getAllocNode(copy.dst, true); + rewrite=true; + } + if (rewrite) { + edgestoremove.add(e); + edgestoadd.add(copy); + } + } + } + for(Edge e:edgestoremove) { + if (!graph.callerEdges.contains(e)) + delta.removeVarEdge(e); + } + for(Edge e:edgestoadd) { + delta.addVarEdge(e); + } + } + + public Alloc getAllocationSiteFromFlatNew(FlatNew node) { + return allocFactory.getAllocNode(node, false).getAllocSite(); + } + + void processSumHeapEdgeSet(HashMap> map, Delta delta, Graph graph) { + MySet edgestoadd=new MySet(); + MySet edgestoremove=new MySet(); + for(Iterator>> eit=map.entrySet().iterator();eit.hasNext();) { + Map.Entry> entry=eit.next(); + AllocNode node=entry.getKey(); + MySet edgeset=entry.getValue(); + + for(Edge e:edgeset) { + Edge copy=e.copy(); + boolean rewrite=false; + if (copy.src!=null&&graph.callNodeAges.contains(copy.src)) { + copy.src=allocFactory.getAllocNode(copy.src, true); + rewrite=true; + } + if (copy.dst!=null&&graph.callNodeAges.contains(copy.dst)) { + copy.dst=allocFactory.getAllocNode(copy.dst, true); + rewrite=true; + } + if (rewrite) { + edgestoremove.add(e); + edgestoadd.add(copy); + } + } + } + for(Edge e:edgestoremove) { + if (!graph.callerEdges.contains(e)) + delta.removeHeapEdge(e); + } + for(Edge e:edgestoadd) { + delta.addHeapEdge(e); + } + } + + //Handle external edges + void processCallExternal(Graph graph, Delta newDelta, MySet externalEdgeSet) { + //Add external edges in + for(Edge e:externalEdgeSet) { + //First did we age the source + Edge newedge=e.copy(); + if (newedge.src!=null&&!e.src.isSummary()&&graph.callNodeAges.contains(e.src)) { + AllocNode summaryNode=allocFactory.getAllocNode(newedge.src, true); + newedge.src=summaryNode; + } + //Compute target + if (graph.callNodeAges.contains(e.dst)&&!e.dst.isSummary()) { + if (graph.callOldNodes.contains(e.dst)) { + //Need two edges + Edge copy=newedge.copy(); + mergeEdge(graph, newDelta, copy); + } + //Now add summarized node + newedge.dst=allocFactory.getAllocNode(newedge.dst, true); + mergeCallEdge(graph, newDelta, newedge); + } else { + //Add edge to single node + mergeEdge(graph, newDelta, newedge); + } + } + } + /* This function applies callee deltas to the caller heap. */ Delta applyCallDelta(Delta delta, BBlock bblock) { @@ -683,72 +1098,94 @@ public class Pointer { Graph oldgraph=(ppoint.getIndex()==0)? bbgraphMap.get(bblock): graphMap.get(nodes.get(ppoint.getIndex()-1)); + Set seseCallers=OoOJava?taskAnalysis.getTransitiveExecutingRBlocks(fcall):null; //Age outside nodes if necessary for(Iterator nodeit=delta.addNodeAges.iterator();nodeit.hasNext();) { AllocNode node=nodeit.next(); if (!graph.callNodeAges.contains(node)) { graph.callNodeAges.add(node); - } else { - nodeit.remove(); + newDelta.addNodeAges.add(node); } if (!graph.reachNode.contains(node)&&!node.isSummary()) { /* Need to age node in existing graph*/ summarizeInGraph(graph, newDelta, node); } + if (graph.callNewEdges.containsKey(node)) { + for(Iterator eit=graph.callNewEdges.get(node).iterator();eit.hasNext();) { + Edge e=eit.next(); + if ((graph.callNodeAges.contains(e.src)||graph.reachNode.contains(e.src))&& + (graph.callNodeAges.contains(e.dst)||graph.reachNode.contains(e.dst))) { + Edge edgetoadd=e.copy();//we need our own copy to modify below + eit.remove(); + if (seseCallers!=null) + edgetoadd.taintModify(seseCallers); + mergeCallEdge(graph, newDelta, edgetoadd); + } + } + } } + //Add heap edges in for(Map.Entry> entry:delta.heapedgeadd.entrySet()) { for(Edge e:entry.getValue()) { boolean addedge=false; Edge edgetoadd=null; if (e.statuspredicate==Edge.NEW) { - edgetoadd=e; + if ((graph.callNodeAges.contains(e.src)||graph.reachNode.contains(e.src))&& + (graph.callNodeAges.contains(e.dst)||graph.reachNode.contains(e.dst))) { + edgetoadd=e.copy();//we need our own copy to modify below + } else { + graph.addCallEdge(e); + } } else { - Edge origEdgeKey=e.makeStatus(allocFactory); - if (oldgraph.nodeMap.containsKey(origEdgeKey.src)&& - oldgraph.nodeMap.get(origEdgeKey.src).contains(origEdgeKey)) { - Edge origEdge=oldgraph.nodeMap.get(origEdgeKey.src).get(origEdgeKey); - //copy the predicate - origEdgeKey.statuspredicate=origEdge.statuspredicate; - edgetoadd=origEdgeKey; + Edge[] edgeArray=e.makeStatus(allocFactory); + + int statuspredicate=0; + for(int i=0;i()); + } + if (graph.callOldEdges.get(origEdgeKey).contains(e)) { + Edge olde=graph.callOldEdges.get(origEdgeKey).get(e); + graph.callOldEdges.get(origEdgeKey).add(olde.merge(e)); + } else { + graph.callOldEdges.get(origEdgeKey).add(e); + } + } + if (statuspredicate!=0) { + Edge newe=e.copy(); + newe.statuspredicate=statuspredicate; + edgetoadd=newe; } } - mergeEdge(graph, newDelta, edgetoadd); - } - } - //Add external edges in - for(Edge e:graph.externalEdgeSet) { - //First did we age the source - Edge newedge=e.copy(); - if (newedge.src!=null&&!e.src.isSummary()&&graph.callNodeAges.contains(e.src)) { - AllocNode summaryNode=allocFactory.getAllocNode(newedge.src, true); - newedge.src=summaryNode; - } - //Compute target - if (graph.callNodeAges.contains(e.dst)&&!e.dst.isSummary()) { - if (graph.callOldNodes.contains(e.dst)) { - //Need two edges - Edge copy=newedge.copy(); - mergeEdge(graph, newDelta, copy); - } - //Now add summarized node - newedge.dst=allocFactory.getAllocNode(newedge.dst, true); - mergeEdge(graph, newDelta, newedge); - } else { - //Add edge to single node - mergeEdge(graph, newDelta, newedge); + if (seseCallers!=null&&edgetoadd!=null) + edgetoadd.taintModify(seseCallers); + mergeCallEdge(graph, newDelta, edgetoadd); } } + + processCallExternal(graph, newDelta, graph.externalEdgeSet); + //Add edge for return value if (fcall.getReturnTemp()!=null) { MySet returnedge=delta.varedgeadd.get(returntmp); if (returnedge!=null) for(Edge e:returnedge) { + //skip the edge if types don't allow it... + if (!typeUtil.isSuperorType(fcall.getReturnTemp().getType(), e.dst.getType())) + continue; Edge newedge=e.copy(); newedge.srcvar=fcall.getReturnTemp(); - if (graph.getEdges(fcall.getReturnTemp())==null||!graph.getEdges(fcall.getReturnTemp()).contains(newedge)) - newDelta.addEdge(newedge); + if (seseCallers!=null) + newedge.taintModify(seseCallers); + mergeEdge(graph, newDelta, newedge); } } applyDiffs(graph, newDelta); @@ -766,6 +1203,22 @@ public class Pointer { } } + /* This is a call produced edge...need to remember this */ + + public void mergeCallEdge(Graph graph, Delta newDelta, Edge edgetoadd) { + if (edgetoadd!=null) { + newDelta.addEdgeClear(edgetoadd); + + Edge match=graph.getMatch(edgetoadd); + + if (match==null||!match.subsumes(edgetoadd)) { + Edge mergededge=edgetoadd.merge(match); + newDelta.addEdge(mergededge); + graph.callerEdges.add(mergededge); + } + } + } + /* Summarizes out of context nodes in graph */ void summarizeInGraph(Graph graph, Delta newDelta, AllocNode singleNode) { @@ -778,7 +1231,7 @@ public class Pointer { Edge rewrite=e.rewrite(singleNode, summaryNode); //Remove old edge newDelta.removeHeapEdge(e); - mergeEdge(graph, newDelta, rewrite); + mergeCallEdge(graph, newDelta, rewrite); } //Handle incoming edges @@ -787,9 +1240,11 @@ public class Pointer { if (e.dst==singleNode) { //Need to get original edge so that predicate will be correct Edge match=graph.getMatch(e); - Edge rewrite=match.rewrite(singleNode, summaryNode); - newDelta.removeEdge(match); - mergeEdge(graph, newDelta, rewrite); + if (match!=null) { + Edge rewrite=match.rewrite(singleNode, summaryNode); + newDelta.removeEdge(match); + mergeCallEdge(graph, newDelta, rewrite); + } } } } @@ -860,7 +1315,7 @@ public class Pointer { else graph.nodeMap.put(node, new MySet()); } - graph.nodeMap.get(node).addAll(edgestoadd); + Edge.mergeEdgesInto(graph.nodeMap.get(node),edgestoadd); if (genbackwards) { for(Edge eadd:edgestoadd) { if (!graph.backMap.containsKey(eadd.dst)) @@ -891,8 +1346,11 @@ public class Pointer { TempDescriptor tmp=e.getKey(); MySet edgestoadd=e.getValue(); if (graph.varMap.containsKey(tmp)) { - graph.varMap.get(tmp).addAll(edgestoadd); - } else + Edge.mergeEdgesInto(graph.varMap.get(tmp), edgestoadd); + } else if (graph.parent.varMap.containsKey(tmp)) { + graph.varMap.put(tmp, new MySet(graph.parent.varMap.get(tmp))); + Edge.mergeEdgesInto(graph.varMap.get(tmp), edgestoadd); + } else graph.varMap.put(tmp, (MySet) edgestoadd.clone()); if (genbackwards) { for(Edge eadd:edgestoadd) { @@ -915,6 +1373,30 @@ public class Pointer { } } + boolean isINACC(FlatNode node) { + if (!OoOJava) + return false; + switch(node.kind()) { + case FKind.FlatSetFieldNode: { + FlatSetFieldNode n=(FlatSetFieldNode)node; + return !accessible.isAccessible(n, n.getDst()); + } + case FKind.FlatSetElementNode: { + FlatSetElementNode n=(FlatSetElementNode)node; + return !accessible.isAccessible(n, n.getDst()); + } + case FKind.FlatFieldNode: { + FlatFieldNode n=(FlatFieldNode)node; + return !accessible.isAccessible(n, n.getSrc()); + } + case FKind.FlatElementNode: { + FlatElementNode n=(FlatElementNode)node; + return !accessible.isAccessible(n, n.getSrc()); + } + } + return false; + } + Delta processSetFieldElementNode(FlatNode node, Delta delta, Graph graph) { TempDescriptor src; FieldDescriptor fd; @@ -930,42 +1412,92 @@ public class Pointer { fd=ffn.getField(); dst=ffn.getDst(); } + if (delta.getInit()) { - HashSet srcNodes=GraphManip.getNodes(graph, delta, src); - HashSet dstNodes=GraphManip.getNodes(graph, delta, dst); - MySet edgesToAdd=GraphManip.genEdges(dstNodes, fd, srcNodes); + MySet dstEdges=GraphManip.getEdges(graph, delta, dst); + + if (OoOJava&&!accessible.isAccessible(node, dst)) { + Taint dstStallTaint=Taint.factory(node, dst, AllocFactory.dummySite, null, ReachGraph.predsEmpty); + dstEdges=Edge.taintAll(dstEdges, dstStallTaint); + updateVarDelta(graph, delta, dst, dstEdges, null); + } + if (OoOJava) { + effectsAnalysis.analyzeFlatSetFieldNode(dstEdges, fd, node); + } + + //Do nothing for non pointers + if (!src.getType().isPtr()) { + if (mustProcess.contains(node)) { + applyDiffs(graph, delta); + } + return delta; + } + + MySet srcEdges=GraphManip.getEdges(graph, delta, src); + if (OoOJava&&!accessible.isAccessible(node, src)) { + Taint srcStallTaint=Taint.factory(node, src, AllocFactory.dummySite, null, ReachGraph.predsEmpty); + srcEdges=Edge.taintAll(srcEdges, srcStallTaint); + updateVarDelta(graph, delta, src, srcEdges, null); + } + + MySet edgesToAdd=GraphManip.genEdges(dstEdges, fd, srcEdges); MySet edgesToRemove=null; - if (dstNodes.size()==1&&!dstNodes.iterator().next().isSummary()&&fd!=null) { + if (dstEdges.size()==1&&!dstEdges.iterator().next().dst.isSummary()&&fd!=null) { /* Can do a strong update */ - edgesToRemove=GraphManip.getEdges(graph, delta, dstNodes, fd); + edgesToRemove=GraphManip.getEdges(graph, delta, dstEdges, fd); graph.strongUpdateSet=edgesToRemove; } else graph.strongUpdateSet=new MySet(); + /* Update diff */ updateHeapDelta(graph, delta, edgesToAdd, edgesToRemove); applyDiffs(graph, delta); } else { - /* First look at new sources */ + MySet newDstEdges=GraphManip.getDiffEdges(delta, dst); + + if (OoOJava&&!accessible.isAccessible(node, dst)) { + Taint dstStallTaint=Taint.factory(node, dst, AllocFactory.dummySite, null, ReachGraph.predsEmpty); + newDstEdges=Edge.taintAll(newDstEdges, dstStallTaint); + updateVarDelta(graph, delta, dst, newDstEdges, null); + } + + if (OoOJava) { + effectsAnalysis.analyzeFlatSetFieldNode(newDstEdges, fd, node); + } + + if (!src.getType().isPtr()) { + if (mustProcess.contains(node)) { + applyDiffs(graph, delta); + } + return delta; + } + + /* Next look at new sources */ + MySet edgesToAdd=new MySet(); - HashSet newSrcNodes=GraphManip.getDiffNodes(delta, src); - HashSet srcNodes=GraphManip.getNodes(graph, delta, src); + MySet newSrcEdges=GraphManip.getDiffEdges(delta, src); + MySet srcEdges=GraphManip.getEdges(graph, delta, src); HashSet dstNodes=GraphManip.getNodes(graph, delta, dst); - HashSet newDstNodes=GraphManip.getDiffNodes(delta, dst); + if (OoOJava&&!accessible.isAccessible(node, src)) { + Taint srcStallTaint=Taint.factory(node, src, AllocFactory.dummySite, null, ReachGraph.predsEmpty); + newSrcEdges=Edge.taintAll(newSrcEdges, srcStallTaint); + updateVarDelta(graph, delta, src, newSrcEdges, null); + } MySet edgesToRemove=null; - if (newDstNodes.size()!=0) { + if (newDstEdges.size()!=0) { if (dstNodes.size()>1&&!dstNodes.iterator().next().isSummary()&&fd!=null) { /* Need to undo strong update */ if (graph.strongUpdateSet!=null) { edgesToAdd.addAll(graph.strongUpdateSet); graph.strongUpdateSet=null; //Prevent future strong updates } - } else if (dstNodes.size()==1&&newDstNodes.size()==1&&!newDstNodes.iterator().next().isSummary()&&graph.strongUpdateSet!=null&&fd!=null) { + } else if (dstNodes.size()==1&&newDstEdges.size()==1&&!newDstEdges.iterator().next().dst.isSummary()&&graph.strongUpdateSet!=null&&fd!=null) { edgesToRemove=GraphManip.getEdges(graph, delta, dstNodes, fd); graph.strongUpdateSet.addAll(edgesToRemove); } - edgesToAdd.addAll(GraphManip.genEdges(newDstNodes, fd, srcNodes)); + Edge.mergeEdgesInto(edgesToAdd, GraphManip.genEdges(newDstEdges, fd, srcEdges)); } //Kill new edges @@ -979,7 +1511,7 @@ public class Pointer { } //Next look at new destinations - edgesToAdd.addAll(GraphManip.genEdges(dstNodes, fd, newSrcNodes)); + Edge.mergeEdgesInto(edgesToAdd, GraphManip.genEdges(dstNodes, fd, newSrcEdges)); /* Update diff */ updateHeapDelta(graph, delta, edgesToAdd, edgesToRemove); @@ -1010,17 +1542,17 @@ public class Pointer { dst=fcn.getDst(); } if (delta.getInit()) { - HashSet srcnodes=GraphManip.getNodes(graph, delta, src); - MySet edgesToAdd=GraphManip.genEdges(dst, srcnodes); + MySet srcedges=GraphManip.getEdges(graph, delta, src); + MySet edgesToAdd=GraphManip.genEdges(dst, srcedges); MySet edgesToRemove=GraphManip.getEdges(graph, delta, dst); updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove); applyDiffs(graph, delta); } else { /* First compute new src nodes */ - HashSet newSrcNodes=GraphManip.getDiffNodes(delta, src); + MySet newSrcEdges=GraphManip.getDiffEdges(delta, src); /* Compute the union, and then the set of edges */ - MySet edgesToAdd=GraphManip.genEdges(dst, newSrcNodes); + MySet edgesToAdd=GraphManip.genEdges(dst, newSrcEdges); /* Compute set of edges to remove */ MySet edgesToRemove=GraphManip.getDiffEdges(delta, dst); @@ -1036,6 +1568,8 @@ public class Pointer { TempDescriptor src; FieldDescriptor fd; TempDescriptor dst; + TaintSet taint=null; + if (node.kind()==FKind.FlatElementNode) { FlatElementNode fen=(FlatElementNode) node; src=fen.getSrc(); @@ -1047,33 +1581,65 @@ public class Pointer { fd=ffn.getField(); dst=ffn.getDst(); } + if (OoOJava&&!accessible.isAccessible(node, src)) { + taint=TaintSet.factory(Taint.factory(node, src, AllocFactory.dummySite, null, ReachGraph.predsEmpty)); + } + + //Do nothing for non pointers if (delta.getInit()) { - HashSet srcnodes=GraphManip.getNodes(graph, delta, src); - HashSet fdnodes=GraphManip.getNodes(graph, delta, srcnodes, fd); - MySet edgesToAdd=GraphManip.genEdges(dst, fdnodes); + MySet srcedges=GraphManip.getEdges(graph, delta, src); + if (OoOJava) { + if (taint!=null) { + srcedges=Edge.taintAll(srcedges, taint); + updateVarDelta(graph, delta, src, srcedges, null); + } + effectsAnalysis.analyzeFlatFieldNode(srcedges, fd, node); + } + if (!dst.getType().isPtr()) { + if (mustProcess.contains(node)) { + applyDiffs(graph, delta); + } + return delta; + } + + MySet edgesToAdd=GraphManip.dereference(graph, delta, dst, srcedges, fd, node); MySet edgesToRemove=GraphManip.getEdges(graph, delta, dst); + updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove); applyDiffs(graph, delta); } else { + MySet newsrcedges=GraphManip.getDiffEdges(delta, src); + if (OoOJava) { + if (taint!=null) { + newsrcedges=Edge.taintAll(newsrcedges, taint); + updateVarDelta(graph, delta, src, newsrcedges, null); + } + effectsAnalysis.analyzeFlatFieldNode(newsrcedges, fd, node); + } + if (!dst.getType().isPtr()) { + if (mustProcess.contains(node)) { + applyDiffs(graph, delta); + } + return delta; + } /* First compute new objects we read fields of */ - HashSet allsrcnodes=GraphManip.getNodes(graph, delta, src); - HashSet difffdnodes=GraphManip.getDiffNodes(delta, allsrcnodes, fd); + MySet allsrcedges=GraphManip.getEdges(graph, delta, src); + MySet edgesToAdd=GraphManip.diffDereference(delta, dst, allsrcedges, fd, node); /* Next compute new targets of fields */ - HashSet newsrcnodes=GraphManip.getDiffNodes(delta, src); - HashSet newfdnodes=GraphManip.getNodes(graph, delta, newsrcnodes, fd); + MySet newfdedges=GraphManip.dereference(graph, delta, dst, newsrcedges, fd, node); + /* Compute the union, and then the set of edges */ - HashSet newTargets=new HashSet(); - newTargets.addAll(newfdnodes); - newTargets.addAll(difffdnodes); - MySet edgesToAdd=GraphManip.genEdges(dst, newTargets); + Edge.mergeEdgesInto(edgesToAdd, newfdedges); /* Compute set of edges to remove */ MySet edgesToRemove=GraphManip.getDiffEdges(delta, dst); + /* Update diff */ updateVarDelta(graph, delta, dst, edgesToAdd, edgesToRemove); applyDiffs(graph, delta); } + return delta; } @@ -1081,21 +1647,31 @@ public class Pointer { MySet edgeAdd=delta.varedgeadd.get(tmp); MySet edgeRemove=delta.varedgeremove.get(tmp); MySet existingEdges=graph.getEdges(tmp); - for(Edge e: edgestoRemove) { - //remove edge from delta - if (edgeAdd!=null) - edgeAdd.remove(e); - //if the edge is already in the graph, add an explicit remove to the delta - if (existingEdges.contains(e)) - delta.removeVarEdge(e); - } + if (edgestoRemove!=null) + for(Edge e: edgestoRemove) { + //remove edge from delta + if (edgeAdd!=null) + edgeAdd.remove(e); + //if the edge is already in the graph, add an explicit remove to the delta + if (existingEdges.contains(e)) + delta.removeVarEdge(e); + } for(Edge e: edgestoAdd) { //Remove the edge from the remove set if (edgeRemove!=null) edgeRemove.remove(e); //Explicitly add it to the add set unless it is already in the graph - if (!existingEdges.contains(e)&&typeUtil.isSuperorType(tmp.getType(),e.dst.getType())) - delta.addVarEdge(e); + if (typeUtil.isSuperorType(tmp.getType(), e.dst.getType())) { + if (!existingEdges.contains(e)) { + delta.addVarEdge(e); + } else { + //See if the old edge subsumes the new one + Edge olde=existingEdges.get(e); + if (!olde.subsumes(e)) { + delta.addVarEdge(olde.merge(e)); + } + } + } } } @@ -1122,8 +1698,14 @@ public class Pointer { if (edgeRemove!=null) edgeRemove.remove(e); //Explicitly add it to the add set unless it is already in the graph - if ((!existingEdges.contains(e)||!existingEdges.get(e).isNew())&&(e.fd==null||typeUtil.isSuperorType(e.fd.getType(), e.dst.getType()))) { + if (!existingEdges.contains(e)) { delta.addHeapEdge(e); + } else { + //See if the old edge subsumes the new one + Edge olde=existingEdges.get(e); + if (!olde.subsumes(e)) { + delta.addHeapEdge(olde.merge(e)); + } } } } @@ -1155,8 +1737,6 @@ public class Pointer { MySet oldedges=graph.getEdges(tmp); if (!oldedges.isEmpty()) delta.varedgeremove.put(tmp, (MySet) oldedges); - //Apply incoming diffs to graph - applyDiffs(graph, delta); //Note that we create a single node delta.addNodeAges.add(single); //Kill the old node @@ -1186,12 +1766,18 @@ public class Pointer { if (entrytmp==tmp) { /* Check is this is the tmp we overwrite, if so add to remove set */ Util.relationUpdate(delta.varedgeremove, tmp, null, entry.getValue()); - } else { + } else if (graph.varMap.containsKey(entrytmp)) { /* Check if the target of the edge is changed */ MySet newset=(MySet)entry.getValue().clone(); MySet removeset=shrinkSet(newset, graph.varMap.get(entrytmp), single, summary); Util.relationUpdate(delta.varedgeremove, entrytmp, newset, removeset); Util.relationUpdate(delta.varedgeadd, entrytmp, null, newset); + } else { + /* Check if the target of the edge is changed */ + MySet newset=(MySet)entry.getValue().clone(); + MySet removeset=shrinkSet(newset, graph.parent.varMap.get(entrytmp), single, summary); + Util.relationUpdate(delta.varedgeremove, entrytmp, newset, removeset); + Util.relationUpdate(delta.varedgeadd, entrytmp, null, newset); } } @@ -1249,9 +1835,10 @@ public class Pointer { delta.addOldNodes.put(single, Boolean.FALSE); } - //Apply incoming diffs to graph - applyDiffs(graph, delta); } + //Apply incoming diffs to graph + applyDiffs(graph, delta); + return delta; } @@ -1380,7 +1967,6 @@ public class Pointer { MySet dstedges=graph.nodeMap.get(nsrc); MySet diffedges=new MySet(); for(Edge e:edges) { - if (!dstedges.contains(e)) { //We have a new edge diffedges.add(e); @@ -1431,6 +2017,13 @@ public class Pointer { //We have a new edge diffedges.add(e); dstedges.add(e); + } else { + Edge origedge=dstedges.get(e); + if (!origedge.subsumes(e)) { + Edge mergededge=origedge.merge(e); + diffedges.add(mergededge); + dstedges.add(mergededge); + } } } //Done with edge set...