--- /dev/null
+package Analysis.Pointer;
+
+import java.util.*;
+import IR.*;
+import IR.Flat.*;
+
+public class AllocFactory {
+ public static class AllocNode {
+ int allocsite;
+ boolean summary;
+ TypeDescriptor type;
+
+ public AllocNode(int allocsite, TypeDescriptor type, boolean summary) {
+ this.allocsite=allocsite;
+ this.summary=summary;
+ this.type=type;
+ }
+
+ public int hashCode() {
+ return allocsite<<1^(summary?0:1);
+ }
+
+ public boolean equals(Object o) {
+ if (o instanceof AllocNode) {
+ AllocNode an=(AllocNode)o;
+ return (allocsite==an.allocsite)&&(summary==an.summary);
+ }
+ return false;
+ }
+ }
+
+ public AllocFactory(State state, TypeUtil typeUtil) {
+ allocMap=new HashMap<FlatNode, Integer>();
+ this.typeUtil=typeUtil;
+ ClassDescriptor stringcd=typeUtil.getClass(TypeUtil.StringClass);
+ TypeDescriptor stringtd=new TypeDescriptor(stringcd);
+ TypeDescriptor stringarraytd=stringtd.makeArray(state);
+ StringArray=new AllocNode(0, stringarraytd, false);
+ Strings=new AllocNode(1, stringtd, true);
+ }
+
+ HashMap<FlatNode, Integer> allocMap;
+ TypeUtil typeUtil;
+ int siteCounter=2;
+
+ public AllocNode StringArray;
+ public AllocNode Strings;
+}
\ No newline at end of file
--- /dev/null
+package Analysis.Pointer;
+import Analysis.Disjoint.PointerMethod;
+import java.util.*;
+import IR.Flat.*;
+
+public class BasicBlock {
+ public BBlock start;
+ public BBlock exit;
+
+ public BasicBlock(BBlock start, BBlock exit) {
+ this.start=start;
+ this.exit=exit;
+ }
+
+ public BBlock getStart() {
+ return start;
+ }
+
+ public BBlock getExit() {
+ return exit;
+ }
+
+ public static class BBlock {
+ Vector<FlatNode> nodes;
+ Vector<BBlock> prevb;
+ Vector<BBlock> nextb;
+
+ public BBlock() {
+ nodes=new Vector<FlatNode>();
+ prevb=new Vector<BBlock>();
+ nextb=new Vector<BBlock>();
+ }
+
+ public Vector<FlatNode> nodes() {
+ return nodes;
+ }
+ public Vector<BBlock> next() {
+ return nextb;
+ }
+ public Vector<BBlock> prev() {
+ return prevb;
+ }
+ }
+
+ public static BasicBlock getBBlock(FlatMethod fm) {
+ BBlock exit=null;
+ Stack<FlatNode> toprocess=new Stack<FlatNode>();
+ HashMap<FlatNode, BBlock> map=new HashMap<FlatNode, BBlock>();
+ PointerMethod pm=new PointerMethod();
+ pm.analyzeMethod(fm);
+ toprocess.add(fm);
+ map.put(fm, new BBlock());
+
+ while(!toprocess.isEmpty()) {
+ FlatNode fn=toprocess.pop();
+ BBlock block=map.get(fn);
+ block.nodes.add(fn);
+ if (fn.kind()==FKind.FlatExit)
+ exit=block;
+ do {
+ if (pm.numNext(fn)!=1) {
+ for(int i=0;i<pm.numNext(fn);i++) {
+ FlatNode fnext=pm.getNext(fn,i);
+ if (!map.containsKey(fnext)) {
+ map.put(fn, new BBlock());
+ toprocess.add(fn);
+ }
+ //link block in
+ if (!block.nextb.contains(map.get(fn))) {
+ block.nextb.add(map.get(fn));
+ map.get(fn).prevb.add(block);
+ }
+ }
+ break;
+ }
+ fn=pm.getNext(fn,0);
+ if (fn.numPrev()>1) {
+ //new basic block
+ if (!map.containsKey(fn)) {
+ map.put(fn, new BBlock());
+ toprocess.add(fn);
+ }
+ //link block in
+ if (!block.nextb.contains(map.get(fn))) {
+ block.nextb.add(map.get(fn));
+ map.get(fn).prevb.add(block);
+ }
+ break;
+ }
+ block.nodes.add(fn);
+ } while(true);
+ }
+
+ return new BasicBlock(map.get(fm), exit);
+ }
+}
--- /dev/null
+package Analysis.Pointer;
+import java.util.*;
+import Analysis.Pointer.AllocFactory.AllocNode;
+import Analysis.Pointer.BasicBlock.BBlock;
+import IR.Flat.*;
+
+public class Delta {
+ HashMap<AllocNode, Vector<Edge>> heapedgeremove;
+ HashMap<TempDescriptor, Vector<Edge>> varedgeremove;
+ HashMap<AllocNode, Vector<Edge>> heapedgeadd;
+ HashMap<TempDescriptor, Vector<Edge>> varedgeadd;
+
+ boolean init;
+ BBlock block;
+
+ public Delta(BBlock block, boolean init) {
+ this.heapedgeadd=new HashMap<AllocNode, Vector<Edge>>();
+ this.varedgeadd=new HashMap<TempDescriptor, Vector<Edge>>();
+ this.heapedgeremove=new HashMap<AllocNode, Vector<Edge>>();
+ this.varedgeremove=new HashMap<TempDescriptor, Vector<Edge>>();
+ this.init=init;
+ this.block=block;
+ }
+
+ public void addHeapEdge(AllocNode node, Edge e) {
+ if (!heapedgeadd.containsKey(node))
+ heapedgeadd.put(node, new Vector<Edge>());
+ heapedgeadd.get(node).add(e);
+ }
+
+ public void addVarEdge(TempDescriptor tmp, Edge e) {
+ if (!varedgeadd.containsKey(tmp))
+ varedgeadd.put(tmp, new Vector<Edge>());
+ varedgeadd.get(tmp).add(e);
+ }
+
+ public void setBlock(BBlock block) {
+ this.block=block;
+ }
+
+ public BBlock getBlock() {
+ return block;
+ }
+
+ public boolean getInit() {
+ return init;
+ }
+}
\ No newline at end of file
--- /dev/null
+package Analysis.Pointer;
+import IR.Flat.*;
+import IR.*;
+import Analysis.Pointer.AllocFactory.AllocNode;
+
+public class Edge {
+ FieldDescriptor fd;
+ AllocNode src;
+ TempDescriptor srcvar;
+ AllocNode dst;
+
+ public Edge(AllocNode src, FieldDescriptor fd, AllocNode dst) {
+ this.src=src;
+ this.fd=fd;
+ this.dst=dst;
+ }
+
+ public Edge(TempDescriptor tmp, AllocNode dst) {
+ this.srcvar=tmp;
+ this.dst=dst;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package Analysis.Pointer;
+import java.util.*;
+import Analysis.Disjoint.PointerMethod;
+import Analysis.Pointer.AllocFactory.AllocNode;
+import IR.Flat.*;
+
+public class Graph {
+
+ /* This is field is set is this Graph is just a delta on the parent
+ * graph. */
+
+ Graph parent;
+ HashSet<TempDescriptor> tempset;
+ HashSet<AllocNode> allocset;
+
+ HashMap<AllocNode, Vector<Edge>> nodeMap;
+ HashMap<TempDescriptor, Vector<Edge>> tmpMap;
+
+ public Graph(Graph parent) {
+ nodeMap=new HashMap<AllocNode, Vector<Edge>>();
+ tmpMap=new HashMap<TempDescriptor, Vector<Edge>>();
+ tempset=new HashSet<TempDescriptor>();
+ allocset=new HashSet<AllocNode>();
+
+ this.parent=parent;
+ }
+
+
+}
\ No newline at end of file
--- /dev/null
+package Analysis.Pointer;
+import java.util.*;
+import IR.Flat.*;
+import IR.*;
+import Analysis.Pointer.BasicBlock.BBlock;
+import Analysis.Pointer.AllocFactory.AllocNode;
+
+public class Pointer {
+ HashMap<FlatMethod, BasicBlock> blockMap;
+ HashMap<FlatNode, Graph> graphMap;
+ State state;
+ TypeUtil typeUtil;
+ AllocFactory allocFactory;
+ LinkedList<Delta> toprocess;
+
+ public Pointer(State state, TypeUtil typeUtil) {
+ this.state=state;
+ this.blockMap=new HashMap<FlatMethod, BasicBlock>();
+ this.graphMap=new HashMap<FlatNode, Graph>();
+ this.typeUtil=typeUtil;
+ this.allocFactory=new AllocFactory(state, typeUtil);
+ this.toprocess=new LinkedList<Delta>();
+ }
+
+ public BasicBlock getBBlock(FlatMethod fm) {
+ if (!blockMap.containsKey(fm))
+ blockMap.put(fm, BasicBlock.getBBlock(fm));
+ return blockMap.get(fm);
+ }
+
+ Delta buildInitialContext() {
+ MethodDescriptor md=typeUtil.getMain();
+ FlatMethod fm=state.getMethodFlat(md);
+ BasicBlock bb=getBBlock(fm);
+ BBlock start=bb.getStart();
+ Delta delta=new Delta(start, true);
+ delta.addHeapEdge(allocFactory.StringArray, new Edge(allocFactory.StringArray, null, allocFactory.Strings));
+ delta.addVarEdge(fm.getParameter(0), new Edge(fm.getParameter(0), allocFactory.StringArray));
+ return delta;
+ }
+
+ void doAnalysis() {
+ toprocess.add(buildInitialContext());
+
+ while(!toprocess.isEmpty()) {
+ Delta delta=toprocess.remove();
+ BBlock bblock=delta.getBlock();
+ Vector<FlatNode> nodes=bblock.nodes();
+ FlatNode firstNode=nodes.get(0);
+
+ //Get graph for first node
+ if (!graphMap.containsKey(firstNode)) {
+ graphMap.put(firstNode, new Graph(null));
+ }
+ Graph graph=graphMap.get(firstNode);
+
+ //First entrance is special...
+ if (delta.getInit()) {
+ applyInit(delta, graph);
+ } else {
+ applyDelta(delta, graph);
+ }
+
+ Graph nodeGraph=null;
+ for(int i=1; i<nodes.size();i++) {
+ FlatNode currNode=nodes.get(i);
+ if (!graphMap.containsKey(currNode)) {
+ graphMap.put(currNode, new Graph(graph, nodeGraph));
+ }
+ nodeGraph=graphMap.get(currNode);
+
+ if (delta.getInit()) {
+ applyInitDiff(delta, nodeGraph);
+ } else {
+ applyDeltaDiff(delta, nodeGraph);
+ }
+ }
+ }
+
+ }
+}
\ No newline at end of file