From: bdemsky Date: Wed, 2 Mar 2011 22:05:52 +0000 (+0000) Subject: changes towards making this work X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=647ba9eea1e5a5099f4db2f4df6546d68c92ff00;p=IRC.git changes towards making this work --- diff --git a/Robust/src/Analysis/Pointer/BasicBlock.java b/Robust/src/Analysis/Pointer/BasicBlock.java index 4746bd74..b58ae1e4 100644 --- a/Robust/src/Analysis/Pointer/BasicBlock.java +++ b/Robust/src/Analysis/Pointer/BasicBlock.java @@ -24,6 +24,7 @@ public class BasicBlock { Vector nodes; Vector prevb; Vector nextb; + boolean callReturn; public BBlock() { nodes=new Vector(); @@ -42,7 +43,7 @@ public class BasicBlock { } } - public static BasicBlock getBBlock(FlatMethod fm, boolean breakcalls) { + public static BasicBlock getBBlock(FlatMethod fm) { BBlock exit=null; Stack toprocess=new Stack(); HashMap map=new HashMap(); @@ -58,7 +59,7 @@ public class BasicBlock { if (fn.kind()==FKind.FlatExit) exit=block; do { - if (pm.numNext(fn)!=1||(fn.kind()==FKind.FlatCall&&breakcalls)) { + if (pm.numNext(fn)!=1) { for(int i=0;i> varedgeremove; HashMap> baseheapedge; HashMap> basevaredge; - HashMap addNodeAges; + HashSet baseNodeAges; + HashSet addNodeAges; boolean init; - BBlock block; + PPoint block; + boolean callStart; /* Init is set for false for delta propagations inside of one basic block. */ - public Delta(BBlock block, boolean init) { + public Delta(PPoint block, boolean init) { this.init=init; this.baseheapedge=new HashMap>(); this.basevaredge=new HashMap>(); @@ -27,22 +29,23 @@ public class Delta { this.heapedgeremove=new HashMap>(); this.varedgeadd=new HashMap>(); this.varedgeremove=new HashMap>(); - this.addNodeAges=new HashMap(); + this.baseNodeAges=new HashSet(); + this.addNodeAges=new HashSet(); this.block=block; } private Delta() { } - public BBlock getBlock() { + public PPoint getBlock() { return block; } - public void setBlock(BBlock block) { + public void setBlock(PPoint block) { this.block=block; } - public Delta changeParams(HashMap tmpMap, BBlock bblock) { + public Delta changeParams(HashMap tmpMap, PPoint bblock) { Delta newdelta=new Delta(); newdelta.baseheapedge=baseheapedge; newdelta.basevaredge=basevaredge; @@ -81,7 +84,7 @@ public class Delta { return newdelta; } - public Delta diffBlock(BBlock bblock) { + public Delta diffBlock(PPoint bblock) { Delta newdelta=new Delta(); newdelta.baseheapedge=baseheapedge; newdelta.basevaredge=basevaredge; diff --git a/Robust/src/Analysis/Pointer/Graph.java b/Robust/src/Analysis/Pointer/Graph.java index 7d61e985..09adf72d 100644 --- a/Robust/src/Analysis/Pointer/Graph.java +++ b/Robust/src/Analysis/Pointer/Graph.java @@ -17,19 +17,20 @@ public class Graph { HashSet reachNode; /* Need this information for mapping in callee results */ - HashMap nodeAges; - public static final Integer OLD=new Integer(1); - public static final Integer NEW=new Integer(2); - public static final Integer EITHER=new Integer(3); + HashSet nodeAges; public Graph(Graph parent) { nodeMap=new HashMap>(); backMap=new HashMap>(); varMap=new HashMap>(); - nodeAges=new HashMap(); + nodeAges=new HashSet(); this.parent=parent; } + public boolean containsNode(AllocNode node) { + return nodeAges.contains(node)||parent!=null&&parent.nodeAges.contains(node); + } + public MySet getEdges(TempDescriptor tmp) { if (varMap.containsKey(tmp)) return varMap.get(tmp); diff --git a/Robust/src/Analysis/Pointer/MySet.java b/Robust/src/Analysis/Pointer/MySet.java new file mode 100644 index 00000000..26be393e --- /dev/null +++ b/Robust/src/Analysis/Pointer/MySet.java @@ -0,0 +1,47 @@ +package Analysis.Pointer; +import java.util.*; + +public class MySet extends AbstractSet { + HashMap map; + public MySet() { + map=new HashMap(); + } + + public int size() { + return map.size(); + } + + public void clear() { + map.clear(); + } + + public boolean remove(Object obj) { + return map.remove(obj)!=null; + } + + public boolean add(T obj) { + return map.put(obj, obj)==null; + } + + public boolean contains(Object obj) { + return map.containsKey(obj); + } + + public T get(T obj) { + return map.get(obj); + } + + public boolean isEmpty() { + return map.isEmpty(); + } + + public Iterator iterator() { + return map.keySet().iterator(); + } + + public Object clone() { + MySet cl=new MySet(); + cl.map.putAll(this.map); + return cl; + } +} \ No newline at end of file diff --git a/Robust/src/Analysis/Pointer/PPoint.java b/Robust/src/Analysis/Pointer/PPoint.java new file mode 100644 index 00000000..da75eb0d --- /dev/null +++ b/Robust/src/Analysis/Pointer/PPoint.java @@ -0,0 +1,24 @@ +package Analysis.Pointer; +import Analysis.Pointer.BasicBlock.BBlock; + +public class PPoint { + BBlock bblock; + int index; + public PPoint(BBlock bblock) { + this.bblock=bblock; + this.index=-1; + } + + public PPoint(BBlock bblock, int index) { + this.bblock=bblock; + this.index=index; + } + + public BBlock getBBlock() { + return bblock; + } + + public int getIndex() { + return index; + } +} \ No newline at end of file diff --git a/Robust/src/Analysis/Pointer/Pointer.java b/Robust/src/Analysis/Pointer/Pointer.java index 06ead04f..aaa3e207 100644 --- a/Robust/src/Analysis/Pointer/Pointer.java +++ b/Robust/src/Analysis/Pointer/Pointer.java @@ -9,7 +9,8 @@ public class Pointer { HashMap blockMap; HashMap bbgraphMap; HashMap graphMap; - HashMap> callMap; + HashMap> callMap; + HashMap> returnMap; State state; TypeUtil typeUtil; @@ -22,7 +23,8 @@ public class Pointer { this.blockMap=new HashMap(); this.bbgraphMap=new HashMap(); this.graphMap=new HashMap(); - this.callMap=new HashMap>(); + this.callMap=new HashMap>(); + this.returnMap=new HashMap>(); this.typeUtil=typeUtil; this.allocFactory=new AllocFactory(state, typeUtil); this.toprocess=new LinkedList(); @@ -32,7 +34,7 @@ public class Pointer { public BasicBlock getBBlock(FlatMethod fm) { if (!blockMap.containsKey(fm)) - blockMap.put(fm, BasicBlock.getBBlock(fm, true)); + blockMap.put(fm, BasicBlock.getBBlock(fm)); return blockMap.get(fm); } @@ -41,7 +43,7 @@ public class Pointer { FlatMethod fm=state.getMethodFlat(md); BasicBlock bb=getBBlock(fm); BBlock start=bb.getStart(); - Delta delta=new Delta(start, true); + Delta delta=new Delta(new PPoint(start), true); MySet arrayset=new MySet(); MySet varset=new MySet(); Edge arrayedge=new Edge(allocFactory.StringArray, null, allocFactory.Strings); @@ -58,7 +60,8 @@ public class Pointer { while(!toprocess.isEmpty()) { Delta delta=toprocess.remove(); - BBlock bblock=delta.getBlock(); + PPoint ppoint=delta.getBlock(); + BBlock bblock=ppoint.getBBlock(); Vector nodes=bblock.nodes(); //Build base graph for entrance to this basic block @@ -73,45 +76,55 @@ public class Pointer { graphMap.put(currNode, new Graph(graph)); } nodeGraph=graphMap.get(currNode); - delta=processNode(currNode, delta, nodeGraph); + delta=processNode(bblock, i, currNode, delta, nodeGraph); } generateFinalDelta(bblock, delta, nodeGraph); } } + void buildInitDelta(Graph graph, Delta newDelta) { + //First compute the set of temps + HashSet tmpSet=new HashSet(); + tmpSet.addAll(graph.varMap.keySet()); + tmpSet.addAll(graph.parent.varMap.keySet()); + + //Next build the temp map part of the delta + for(TempDescriptor tmp:tmpSet) { + MySet edgeSet=new MySet(); + /* Get target set */ + if (graph.varMap.containsKey(tmp)) + edgeSet.addAll(graph.varMap.get(tmp)); + else + edgeSet.addAll(graph.parent.varMap.get(tmp)); + newDelta.varedgeadd.put(tmp, edgeSet); + } + + //Next compute the set of src allocnodes + HashSet nodeSet=new HashSet(); + nodeSet.addAll(graph.nodeMap.keySet()); + nodeSet.addAll(graph.parent.nodeMap.keySet()); + + for(AllocNode node:nodeSet) { + MySet edgeSet=new MySet(); + /* Get edge set */ + if (graph.nodeMap.containsKey(node)) + edgeSet.addAll(graph.nodeMap.get(node)); + else + 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); + } + } + void generateFinalDelta(BBlock bblock, Delta delta, Graph graph) { Delta newDelta=new Delta(null, false); if (delta.getInit()) { - //First compute the set of temps - HashSet tmpSet=new HashSet(); - tmpSet.addAll(graph.varMap.keySet()); - tmpSet.addAll(graph.parent.varMap.keySet()); - - //Next build the temp map part of the delta - for(TempDescriptor tmp:tmpSet) { - MySet edgeSet=new MySet(); - /* Get target set */ - if (graph.varMap.containsKey(tmp)) - edgeSet.addAll(graph.varMap.get(tmp)); - else - edgeSet.addAll(graph.parent.varMap.get(tmp)); - newDelta.varedgeadd.put(tmp, edgeSet); - } - - //Next compute the set of src allocnodes - HashSet nodeSet=new HashSet(); - nodeSet.addAll(graph.nodeMap.keySet()); - nodeSet.addAll(graph.parent.nodeMap.keySet()); - - for(AllocNode node:nodeSet) { - MySet edgeSet=new MySet(); - /* Get edge set */ - if (graph.nodeMap.containsKey(node)) - edgeSet.addAll(graph.nodeMap.get(node)); - else - edgeSet.addAll(graph.parent.nodeMap.get(node)); - newDelta.heapedgeadd.put(node, edgeSet); - } + buildInitDelta(graph, newDelta); } else { /* We can break the old delta...it is done being used */ /* First we will build variable edges */ @@ -145,27 +158,33 @@ public class Pointer { /* Also need to subtract off some edges */ MySet removeset=delta.heapedgeremove.get(node); + /* Remove the newly created edges..no need to propagate a diff for those */ removeset.removeAll(delta.baseheapedge.get(node)); newDelta.heapedgeremove.put(node, removeset); } + + /* Compute new ages */ + newDelta.addNodeAges.addAll(delta.baseNodeAges); + newDelta.addNodeAges.addAll(delta.addNodeAges); } + /* Now we need to propagate newdelta */ - if (!newDelta.heapedgeadd.isEmpty()||!newDelta.heapedgeremove.isEmpty()||!newDelta.varedgeadd.isEmpty()) { + if (!newDelta.heapedgeadd.isEmpty()||!newDelta.heapedgeremove.isEmpty()||!newDelta.varedgeadd.isEmpty()||!newDelta.addNodeAges.isEmpty()) { /* We have a delta to propagate */ Vector blockvector=bblock.next(); for(int i=0;i edges=GraphManip.getEdges(graph, delta, node); - newDelta.heapedgeadd.put(node, GraphManip.makeOld(edges)); + newDelta.heapedgeadd.put(node, edges); edgeset.addAll(edges); for(Edge e:edges) { if (!nodeset.contains(e.dst)) { @@ -266,6 +285,7 @@ public class Pointer { } } + //Fix mapping for(MethodDescriptor calledmd:targets) { FlatMethod fm=state.getMethodFlat(calledmd); @@ -285,23 +305,38 @@ public class Pointer { BasicBlock block=getBBlock(fm); //Build and enqueue delta - Delta d=newDelta.changeParams(tmpMap, block.getStart()); + Delta d=newDelta.changeParams(tmpMap, new PPoint(block.getStart())); toprocess.add(d); //Hook up exits - if (!callMap.containsKey(delta.getBlock())) { - callMap.put(delta.getBlock(), new HashSet()); + if (!callMap.containsKey(fcall)) { + callMap.put(fcall, new HashSet()); } - callMap.get(delta.getBlock()).add(block.getStart()); + callMap.get(fcall).add(block.getStart()); - //Hook up returns - for(BBlock retblock:delta.getBlock().next()) { - //Hook up exits - if (!callMap.containsKey(block.getExit())) { - callMap.put(block.getExit(), new HashSet()); + //If we have an existing exit, build delta + Delta returnDelta=null; + + //Hook up return + if (!returnMap.containsKey(block.getExit())) { + returnMap.put(block.getExit(), new HashSet()); + } + returnMap.get(block.getExit()).add(new PPoint(callblock, callindex)); + + if (bbgraphMap.containsKey(block.getExit())) { + //Need to push existing results to current node + if (returnDelta==null) { + returnDelta=new Delta(null, false); + buildInitDelta(bbgraphMap.get(block.getExit()), returnDelta); + if (!returnDelta.heapedgeadd.isEmpty()||!returnDelta.heapedgeremove.isEmpty()||!returnDelta.varedgeadd.isEmpty()) { + returnDelta.setBlock(new PPoint(callblock, callindex)); + toprocess.add(returnDelta); + } + } else { + if (!returnDelta.heapedgeadd.isEmpty()||!returnDelta.heapedgeremove.isEmpty()||!returnDelta.varedgeadd.isEmpty()) { + toprocess.add(returnDelta.diffBlock(new PPoint(callblock, callindex))); + } } - callMap.get(block.getExit()).add(retblock); - //NOTE: Need to push deltas here probably } } graph.reachNode=nodeset; @@ -369,7 +404,7 @@ public class Pointer { AllocNode node=tovisit.pop(); MySet edges=GraphManip.getEdges(graph, delta, node); - newDelta.heapedgeadd.put(node, GraphManip.makeOld(edges)); + newDelta.heapedgeadd.put(node, edges); edgeset.addAll(edges); for(Edge e:edges) { if (!nodeset.contains(e.dst)&&!oldnodeset.contains(e.dst)) { @@ -408,21 +443,36 @@ public class Pointer { BasicBlock block=getBBlock(fm); //Hook up exits - if (!callMap.containsKey(delta.getBlock())) { - callMap.put(delta.getBlock(), new HashSet()); + if (!callMap.containsKey(fcall)) { + callMap.put(fcall, new HashSet()); } - - if (!callMap.get(delta.getBlock()).contains(block.getStart())) { - callMap.get(delta.getBlock()).add(block.getStart()); + + Delta returnDelta=null; + + if (!callMap.get(fcall).contains(block.getStart())) { + callMap.get(fcall).add(block.getStart()); newmethod=true; - //Hook up returns - for(BBlock retblock:delta.getBlock().next()) { - //Hook up exits - if (!callMap.containsKey(block.getExit())) { - callMap.put(block.getExit(), new HashSet()); + + //Hook up exits + if (!returnMap.containsKey(block.getExit())) { + returnMap.put(block.getExit(), new HashSet()); + } + returnMap.get(block.getExit()).add(new PPoint(callblock, callindex)); + + if (bbgraphMap.containsKey(block.getExit())) { + //Need to push existing results to current node + if (returnDelta==null) { + returnDelta=new Delta(null, false); + buildInitDelta(bbgraphMap.get(block.getExit()), returnDelta); + if (!returnDelta.heapedgeadd.isEmpty()||!returnDelta.heapedgeremove.isEmpty()||!returnDelta.varedgeadd.isEmpty()) { + returnDelta.setBlock(new PPoint(callblock, callindex)); + toprocess.add(returnDelta); + } + } else { + if (!returnDelta.heapedgeadd.isEmpty()||!returnDelta.heapedgeremove.isEmpty()||!returnDelta.varedgeadd.isEmpty()) { + toprocess.add(returnDelta.diffBlock(new PPoint(callblock, callindex))); + } } - callMap.get(block.getExit()).add(retblock); - //NOTE: Need to push deltas here probably } } @@ -442,11 +492,11 @@ public class Pointer { basedelta=newDelta.buildBase(oldedgeset); } //Build and enqueue delta - Delta d=basedelta.changeParams(tmpMap, block.getStart()); + Delta d=basedelta.changeParams(tmpMap, new PPoint(block.getStart())); toprocess.add(d); } else { //Build and enqueue delta - Delta d=newDelta.changeParams(tmpMap, block.getStart()); + Delta d=newDelta.changeParams(tmpMap, new PPoint(block.getStart())); toprocess.add(d); } } @@ -517,6 +567,11 @@ public class Pointer { MySet edgestoadd=e.getValue(); graph.varMap.put(tmp, (MySet) edgestoadd.clone()); } + + //Add node additions + for(AllocNode node:delta.addNodeAges) { + graph.nodeAges.add(node); + } } Delta processSetFieldElementNode(FlatNode node, Delta delta, Graph graph) { @@ -714,8 +769,13 @@ public class Pointer { AllocNode summary=allocFactory.getAllocNode(node, true); AllocNode single=allocFactory.getAllocNode(node, false); TempDescriptor tmp=node.getDst(); - + if (delta.getInit()) { + /* We don't have to deal with summarization here... The + * intuition is that this is the only place where we generate + * nodes for this allocation site and this is the first time + * we've analyzed this site */ + //Build new Edge Edge e=new Edge(tmp, single); //Build new Edge set @@ -727,6 +787,8 @@ public class Pointer { delta.varedgeremove.put(tmp, graph.getEdges(tmp)); //Apply incoming diffs to graph applyDiffs(graph, delta); + //Note that we create a single node + delta.addNodeAges.add(single); } else { /* 1. Fix up the variable edge additions */ @@ -799,7 +861,15 @@ public class Pointer { Util.relationUpdate(delta.heapedgeadd, addnode, null, newset); Util.relationUpdate(delta.heapedgeremove, allocnode, null, removeset); } - + + /* Update Node Ages...If the base or addNodeAges set contains a + * single node, it now should also contain a summary node... No + * need to generate a single node as that has already been + * done. */ + if (delta.baseNodeAges.contains(single)||delta.addNodeAges.contains(single)) { + delta.addNodeAges.add(summary); + } + //Apply incoming diffs to graph applyDiffs(graph, delta); } @@ -882,13 +952,13 @@ public class Pointer { //Add in var edges and throw away original diff graph.varMap.putAll(delta.varedgeadd); //Record that this is initial set... + graph.nodeAges.addAll(delta.addNodeAges); } else { newdelta=new Delta(null, false); //merge in heap edges and variables mergeHeapEdges(graph, delta, newdelta); mergeVarEdges(graph, delta, newdelta); - //Record that this is a diff - newdelta.setInit(false); + mergeAges(graph, delta, newdelta); } return newdelta; } @@ -948,4 +1018,14 @@ public class Pointer { } } } + + void mergeAges(Graph graph, Delta delta, Delta newDelta) { + //Merge in edges + for(AllocNode node:delta.addNodeAges) { + if (!graph.nodeAges.contains(node)) { + graph.nodeAges.add(node); + newDelta.baseNodeAges.add(node); + } + } + } } \ No newline at end of file