make callgraph an interface
authorbdemsky <bdemsky>
Mon, 18 Apr 2011 21:40:31 +0000 (21:40 +0000)
committerbdemsky <bdemsky>
Mon, 18 Apr 2011 21:40:31 +0000 (21:40 +0000)
Robust/src/Analysis/CallGraph/BaseCallGraph.java [new file with mode: 0644]
Robust/src/Analysis/CallGraph/CallGraph.java
Robust/src/Analysis/CallGraph/JavaCallGraph.java
Robust/src/Main/Main.java

diff --git a/Robust/src/Analysis/CallGraph/BaseCallGraph.java b/Robust/src/Analysis/CallGraph/BaseCallGraph.java
new file mode 100644 (file)
index 0000000..5859300
--- /dev/null
@@ -0,0 +1,396 @@
+package Analysis.CallGraph;
+import IR.State;
+import IR.Flat.FlatMethod;
+import IR.Flat.FlatNode;
+import IR.Flat.FlatCall;
+import IR.Flat.FKind;
+import IR.Descriptor;
+import IR.ClassDescriptor;
+import IR.MethodDescriptor;
+import IR.TaskDescriptor;
+import IR.TypeDescriptor;
+import IR.TypeUtil;
+import java.util.*;
+import java.io.*;
+
+public class BaseCallGraph implements CallGraph {
+  protected State state;
+
+  // MethodDescriptor maps to HashSet<MethodDescriptor>
+  protected Hashtable mapVirtual2ImplementationSet;
+
+  // MethodDescriptor or TaskDescriptor maps to HashSet<MethodDescriptor>
+  protected Hashtable mapCaller2CalleeSet;
+
+  // MethodDescriptor maps to HashSet<MethodDescriptor or TaskDescriptor>
+  protected Hashtable mapCallee2CallerSet;
+
+  protected BaseCallGraph() {}
+
+  protected TypeUtil typeUtil;
+
+  public BaseCallGraph(State state, TypeUtil typeUtil) {
+    this.state=state;
+    this.typeUtil=typeUtil;
+
+    mapVirtual2ImplementationSet = new Hashtable();
+    mapCaller2CalleeSet          = new Hashtable();
+    mapCallee2CallerSet          = new Hashtable();
+    buildVirtualMap();
+    buildGraph();
+  }
+
+  // this method returns the set of Descriptors
+  // (MethodDescriptors and/or TaskDescriptors)
+  //  that call the given method
+  public Set getCallerSet(MethodDescriptor md) {
+    Set s = (Set) mapCallee2CallerSet.get(md);
+    
+    if( s == null ) {
+      return new HashSet();
+    }
+    return s;
+  }
+
+  // this method returns the set of MethodDescriptors that
+  // are called by the given method or task
+  public Set getCalleeSet(Descriptor d) {
+    assert(d instanceof MethodDescriptor) ||
+    (d instanceof TaskDescriptor);
+
+    Set s = (Set) mapCaller2CalleeSet.get(d);
+
+    if( s == null ) {
+      return new HashSet();
+    }
+    return s;
+  }
+
+  // build a mapping of virtual methods to all
+  // possible implementations of that method
+  protected void buildVirtualMap() {
+    //Iterator through classes
+    Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
+    while(it.hasNext()) {
+      ClassDescriptor cn=(ClassDescriptor)it.next();
+      Iterator methodit=cn.getMethods();
+      //Iterator through methods
+      while(methodit.hasNext()) {
+       MethodDescriptor md=(MethodDescriptor)methodit.next();
+       if (md.isStatic()||md.getReturnType()==null)
+         continue;
+       Stack<ClassDescriptor> possInterfaces=new Stack<ClassDescriptor>();
+       ClassDescriptor tmpcd=cn;
+       while(tmpcd!=null) {
+         for(Iterator supit=tmpcd.getSuperInterfaces();supit.hasNext();) {
+           possInterfaces.add((ClassDescriptor)supit.next());
+         }
+         tmpcd=tmpcd.getSuperDesc();
+       }
+       while(!possInterfaces.isEmpty()) {
+         ClassDescriptor IFdesc=possInterfaces.pop();
+         for(Iterator supit=IFdesc.getSuperInterfaces();supit.hasNext();) {
+           possInterfaces.add((ClassDescriptor)supit.next());
+         }
+         Set possiblematches=IFdesc.getMethodTable().getSet(md.getSymbol());
+         boolean foundmatch=false;
+         for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
+           MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
+           if (md.matches(matchmd)) {
+             if (!mapVirtual2ImplementationSet.containsKey(matchmd))
+               mapVirtual2ImplementationSet.put(matchmd,new HashSet());
+             ((HashSet)mapVirtual2ImplementationSet.get(matchmd)).add(md);
+             break;
+           }
+         }
+       }
+       
+
+       ClassDescriptor superdesc=cn.getSuperDesc();
+       if (superdesc!=null) {
+         Set possiblematches=superdesc.getMethodTable().getSet(md.getSymbol());
+         boolean foundmatch=false;
+         for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
+           MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
+           if (md.matches(matchmd)) {
+             if (!mapVirtual2ImplementationSet.containsKey(matchmd))
+               mapVirtual2ImplementationSet.put(matchmd,new HashSet());
+             ((HashSet)mapVirtual2ImplementationSet.get(matchmd)).add(md);
+             break;
+           }
+         }
+       }
+      }
+    }
+  }
+
+  public Set getMethods(MethodDescriptor md, TypeDescriptor type) {
+    return getMethods(md);
+  }
+
+  /** Given a call to MethodDescriptor, lists the methods which
+      could actually be called due to virtual dispatch. */
+  public Set getMethods(MethodDescriptor md) {
+    HashSet ns=new HashSet();
+    ns.add(md);
+    Set s=(Set)mapVirtual2ImplementationSet.get(md);
+    if (s!=null)
+      for(Iterator it=s.iterator(); it.hasNext();) {
+       MethodDescriptor md2=(MethodDescriptor)it.next();
+       ns.addAll(getMethods(md2));
+      }
+    return ns;
+  }
+
+  /** Given a call to MethodDescriptor, lists the methods which
+      could actually be call by that method. */
+  public Set getMethodCalls(TaskDescriptor td) {
+    return getMethodCalls( (Descriptor) td);
+  }
+
+  public Set getMethodCalls(MethodDescriptor md) {
+    return getMethodCalls( (Descriptor) md);
+  }
+
+  public Set getMethodCalls(Descriptor d) {
+    assert d instanceof MethodDescriptor ||
+    d instanceof TaskDescriptor;
+
+    HashSet ns=new HashSet();
+    ns.add(d);
+    return getMoreMethodCalls(ns, d);
+  }
+
+  private Set getMoreMethodCalls(HashSet found, Descriptor d) {
+    HashSet ns=new HashSet();
+    ns.add(d);
+    found.add(d);
+    Set s=(Set)mapCaller2CalleeSet.get(d);
+    if (s!=null)
+      for(Iterator it=s.iterator(); it.hasNext();) {
+       MethodDescriptor md=(MethodDescriptor)it.next();
+       if( !found.contains(md) ) {
+         ns.addAll(getMoreMethodCalls(found, md));
+       }
+      }
+    return ns;
+  }
+
+  public boolean isCallable(MethodDescriptor md) {
+    return true;
+  }
+
+  /** Returns all methods transitively callable from d */
+
+  public Set getAllMethods(Descriptor d) {
+    HashSet tovisit=new HashSet();
+    tovisit.add(d);
+    HashSet callable=new HashSet();
+    while(!tovisit.isEmpty()) {
+      Descriptor md=(Descriptor)tovisit.iterator().next();
+      tovisit.remove(md);
+      Set s=(Set)mapCaller2CalleeSet.get(md);
+
+      if (s!=null) {
+       for(Iterator it=s.iterator(); it.hasNext();) {
+         MethodDescriptor md2=(MethodDescriptor)it.next();
+         if( !callable.contains(md2) ) {
+           callable.add(md2);
+           tovisit.add(md2);
+         }
+       }
+      }
+    }
+    return callable;
+  }
+  
+  // Returns a set of methods containing SESEs and located at the first   
+  // in transitive call chain starting from d 
+  public Set getFirstReachableMethodContainingSESE(Descriptor d,
+      Set<MethodDescriptor> methodsContainingSESEs) {
+    HashSet tovisit = new HashSet();
+    tovisit.add(d);
+    HashSet callable = new HashSet();
+    while (!tovisit.isEmpty()) {
+      Descriptor md = (Descriptor) tovisit.iterator().next();
+      tovisit.remove(md);
+      Set s = (Set) mapCaller2CalleeSet.get(md);
+
+      if (s != null) {
+        for (Iterator it = s.iterator(); it.hasNext();) {
+          MethodDescriptor md2 = (MethodDescriptor) it.next();
+          if (!callable.contains(md2)) {
+            callable.add(md2);
+            if (!methodsContainingSESEs.contains(md2)) {
+              // if current method has sese, do not need to go down
+              tovisit.add(md2);
+            }
+          }
+        }
+      }
+    }
+//    callable.retainAll(methodsContainingSESEs);
+    return callable;
+  }
+  
+
+  private void buildGraph() {
+    Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
+    while(it.hasNext()) {
+      ClassDescriptor cn=(ClassDescriptor)it.next();
+      Iterator methodit=cn.getMethods();
+      //Iterator through methods
+      while(methodit.hasNext()) {
+       MethodDescriptor md=(MethodDescriptor)methodit.next();
+       analyzeMethod( (Object)md, state.getMethodFlat(md) );
+      }
+    }
+    it=state.getTaskSymbolTable().getDescriptorsIterator();
+    while(it.hasNext()) {
+      TaskDescriptor td=(TaskDescriptor)it.next();
+      analyzeMethod( (Object)td, state.getMethodFlat(td) );
+    }
+  }
+
+  protected void analyzeMethod(Object caller, FlatMethod fm) {
+    HashSet toexplore=new HashSet();
+    toexplore.add(fm);
+    HashSet explored=new HashSet();
+    //look at all the nodes in the flat representation
+    while(!toexplore.isEmpty()) {
+      FlatNode fn=(FlatNode)(toexplore.iterator()).next();
+      toexplore.remove(fn);
+      explored.add(fn);
+      for(int i=0; i<fn.numNext(); i++) {
+       FlatNode fnnext=fn.getNext(i);
+       if (!explored.contains(fnnext))
+         toexplore.add(fnnext);
+      }
+      if (fn.kind()==FKind.FlatCall) {
+       FlatCall fc=(FlatCall)fn;
+       MethodDescriptor calledmethod=fc.getMethod();
+       Set methodsthatcouldbecalled=fc.getThis()==null ? getMethods(calledmethod) :
+                                     getMethods(calledmethod, fc.getThis().getType());
+       
+       // add caller -> callee maps
+       if( !mapCaller2CalleeSet.containsKey(caller) ) {
+         mapCaller2CalleeSet.put(caller, new HashSet() );
+       }
+       ((HashSet)mapCaller2CalleeSet.get(caller)).addAll(methodsthatcouldbecalled);
+
+       // add callee -> caller maps
+       Iterator calleeItr = methodsthatcouldbecalled.iterator();
+       while( calleeItr.hasNext() ) {
+         MethodDescriptor callee = (MethodDescriptor) calleeItr.next();
+         if( !mapCallee2CallerSet.containsKey(callee) ) {
+           mapCallee2CallerSet.put(callee, new HashSet() );
+         }
+         ((HashSet)mapCallee2CallerSet.get(callee)).add(caller);
+       }
+      }
+    }
+  }
+
+
+  public void writeVirtual2ImplemToDot(String graphName)  throws java.io.IOException {
+    HashSet labeledInDot = new HashSet();
+
+    BufferedWriter bw = new BufferedWriter(new FileWriter(graphName+".dot") );
+    bw.write("digraph "+graphName+" {\n");
+    Iterator mapItr =  mapVirtual2ImplementationSet.entrySet().iterator();
+    while( mapItr.hasNext() ) {
+      Map.Entry me        = (Map.Entry)mapItr.next();
+      MethodDescriptor virtual   = (MethodDescriptor) me.getKey();
+      HashSet implemSet = (HashSet)          me.getValue();
+
+      if( !labeledInDot.contains(virtual) ) {
+       labeledInDot.add(virtual);
+       bw.write("  "+virtual.getNum()+"[label=\""+virtual+"\"];\n");
+      }
+
+      Iterator implemItr = implemSet.iterator();
+      while( implemItr.hasNext() ) {
+       Descriptor implem = (Descriptor) implemItr.next();
+
+       if( !labeledInDot.contains(implem) ) {
+         labeledInDot.add(implem);
+         bw.write("  "+implem.getNum()+"[label=\""+implem+"\"];\n");
+       }
+
+       bw.write("  "+virtual.getNum()+"->"+implem.getNum()+";\n");
+      }
+    }
+    bw.write("}\n");
+    bw.close();
+  }
+
+
+  public void writeCaller2CalleesToDot(String graphName)  throws java.io.IOException {
+    // write out the call graph (should be equivalent) by
+    // using the callers mapping
+    HashSet labeledInDot = new HashSet();
+    BufferedWriter bw = new BufferedWriter(new FileWriter(graphName+"byCallers.dot") );
+    bw.write("digraph "+graphName+"byCallers {\n");
+    Iterator mapItr = mapCaller2CalleeSet.entrySet().iterator();
+    while( mapItr.hasNext() ) {
+      Map.Entry me      = (Map.Entry)mapItr.next();
+      Descriptor caller = (Descriptor) me.getKey();
+      HashSet calleeSet = (HashSet)    me.getValue();
+
+      if( !labeledInDot.contains(caller) ) {
+       labeledInDot.add(caller);
+       bw.write("  "+caller.getNum()+"[label=\"" +caller+"\"];\n");
+      }
+
+      Iterator calleeItr = calleeSet.iterator();
+      while( calleeItr.hasNext() ) {
+       MethodDescriptor callee = (MethodDescriptor) calleeItr.next();
+
+       if( !labeledInDot.contains(callee) ) {
+         labeledInDot.add(callee);
+         bw.write("  "+callee.getNum()+"[label=\""+callee+"\"];\n");
+       }
+
+       bw.write("  "+caller.getNum()+"->"+callee.getNum()+";\n");
+      }
+    }
+    bw.write("}\n");
+    bw.close();
+  }
+
+
+  public void writeCallee2CallersToDot(String graphName)  throws java.io.IOException {
+    // each task or method only needs to be labeled once
+    // in a dot file
+    HashSet labeledInDot = new HashSet();
+
+    // write out the call graph using the callees mapping
+    BufferedWriter bw = new BufferedWriter(new FileWriter(graphName+"byCallees.dot") );
+    bw.write("digraph "+graphName+"byCallees {\n");
+    Iterator mapItr = mapCallee2CallerSet.entrySet().iterator();
+    while( mapItr.hasNext() ) {
+      Map.Entry me        = (Map.Entry)mapItr.next();
+      MethodDescriptor callee    = (MethodDescriptor) me.getKey();
+      HashSet callerSet = (HashSet)          me.getValue();
+
+      if( !labeledInDot.contains(callee) ) {
+       labeledInDot.add(callee);
+       bw.write("  "+callee.getNum()+"[label=\""+callee+"\"];\n");
+      }
+
+      Iterator callerItr = callerSet.iterator();
+      while( callerItr.hasNext() ) {
+       Descriptor caller = (Descriptor) callerItr.next();
+
+       if( !labeledInDot.contains(caller) ) {
+         labeledInDot.add(caller);
+         bw.write("  "+caller.getNum()+"[label=\""+caller+"\"];\n");
+       }
+
+       bw.write("  "+caller.getNum()+"->"+callee.getNum()+";\n");
+      }
+    }
+    bw.write("}\n");
+    bw.close();
+  }
+}
index 5ed43132aaa5cd744fbb19eaf9c4f28ccb67b2e7..b2f2a9f92b1a23a7be9d216c0579540d312040aa 100644 (file)
@@ -1,4 +1,5 @@
 package Analysis.CallGraph;
+
 import IR.State;
 import IR.Flat.FlatMethod;
 import IR.Flat.FlatNode;
@@ -11,386 +12,15 @@ import IR.TaskDescriptor;
 import IR.TypeDescriptor;
 import IR.TypeUtil;
 import java.util.*;
-import java.io.*;
-
-public class CallGraph {
-  protected State state;
-
-  // MethodDescriptor maps to HashSet<MethodDescriptor>
-  protected Hashtable mapVirtual2ImplementationSet;
-
-  // MethodDescriptor or TaskDescriptor maps to HashSet<MethodDescriptor>
-  protected Hashtable mapCaller2CalleeSet;
-
-  // MethodDescriptor maps to HashSet<MethodDescriptor or TaskDescriptor>
-  protected Hashtable mapCallee2CallerSet;
-
-  protected CallGraph() {}
-
-  protected TypeUtil typeUtil;
-
-  public CallGraph(State state, TypeUtil typeUtil) {
-    this.state=state;
-    this.typeUtil=typeUtil;
-
-    mapVirtual2ImplementationSet = new Hashtable();
-    mapCaller2CalleeSet          = new Hashtable();
-    mapCallee2CallerSet          = new Hashtable();
-    buildVirtualMap();
-    buildGraph();
-  }
-
-  // this method returns the set of Descriptors
-  // (MethodDescriptors and/or TaskDescriptors)
-  //  that call the given method
-  public Set getCallerSet(MethodDescriptor md) {
-    Set s = (Set) mapCallee2CallerSet.get(md);
-    
-    if( s == null ) {
-      return new HashSet();
-    }
-    return s;
-  }
-
-  // this method returns the set of MethodDescriptors that
-  // are called by the given method or task
-  public Set getCalleeSet(Descriptor d) {
-    assert(d instanceof MethodDescriptor) ||
-    (d instanceof TaskDescriptor);
-
-    Set s = (Set) mapCaller2CalleeSet.get(d);
-
-    if( s == null ) {
-      return new HashSet();
-    }
-    return s;
-  }
-
-  // build a mapping of virtual methods to all
-  // possible implementations of that method
-  protected void buildVirtualMap() {
-    //Iterator through classes
-    Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
-    while(it.hasNext()) {
-      ClassDescriptor cn=(ClassDescriptor)it.next();
-      Iterator methodit=cn.getMethods();
-      //Iterator through methods
-      while(methodit.hasNext()) {
-       MethodDescriptor md=(MethodDescriptor)methodit.next();
-       if (md.isStatic()||md.getReturnType()==null)
-         continue;
-       Stack<ClassDescriptor> possInterfaces=new Stack<ClassDescriptor>();
-       ClassDescriptor tmpcd=cn;
-       while(tmpcd!=null) {
-         for(Iterator supit=tmpcd.getSuperInterfaces();supit.hasNext();) {
-           possInterfaces.add((ClassDescriptor)supit.next());
-         }
-         tmpcd=tmpcd.getSuperDesc();
-       }
-       while(!possInterfaces.isEmpty()) {
-         ClassDescriptor IFdesc=possInterfaces.pop();
-         for(Iterator supit=IFdesc.getSuperInterfaces();supit.hasNext();) {
-           possInterfaces.add((ClassDescriptor)supit.next());
-         }
-         Set possiblematches=IFdesc.getMethodTable().getSet(md.getSymbol());
-         boolean foundmatch=false;
-         for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
-           MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
-           if (md.matches(matchmd)) {
-             if (!mapVirtual2ImplementationSet.containsKey(matchmd))
-               mapVirtual2ImplementationSet.put(matchmd,new HashSet());
-             ((HashSet)mapVirtual2ImplementationSet.get(matchmd)).add(md);
-             break;
-           }
-         }
-       }
-       
-
-       ClassDescriptor superdesc=cn.getSuperDesc();
-       if (superdesc!=null) {
-         Set possiblematches=superdesc.getMethodTable().getSet(md.getSymbol());
-         boolean foundmatch=false;
-         for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
-           MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
-           if (md.matches(matchmd)) {
-             if (!mapVirtual2ImplementationSet.containsKey(matchmd))
-               mapVirtual2ImplementationSet.put(matchmd,new HashSet());
-             ((HashSet)mapVirtual2ImplementationSet.get(matchmd)).add(md);
-             break;
-           }
-         }
-       }
-      }
-    }
-  }
-
-  public Set getMethods(MethodDescriptor md, TypeDescriptor type) {
-    return getMethods(md);
-  }
-
-  /** Given a call to MethodDescriptor, lists the methods which
-      could actually be called due to virtual dispatch. */
-  public Set getMethods(MethodDescriptor md) {
-    HashSet ns=new HashSet();
-    ns.add(md);
-    Set s=(Set)mapVirtual2ImplementationSet.get(md);
-    if (s!=null)
-      for(Iterator it=s.iterator(); it.hasNext();) {
-       MethodDescriptor md2=(MethodDescriptor)it.next();
-       ns.addAll(getMethods(md2));
-      }
-    return ns;
-  }
-
-  /** Given a call to MethodDescriptor, lists the methods which
-      could actually be call by that method. */
-  public Set getMethodCalls(TaskDescriptor td) {
-    return getMethodCalls( (Descriptor) td);
-  }
-
-  public Set getMethodCalls(MethodDescriptor md) {
-    return getMethodCalls( (Descriptor) md);
-  }
-
-  public Set getMethodCalls(Descriptor d) {
-    assert d instanceof MethodDescriptor ||
-    d instanceof TaskDescriptor;
-
-    HashSet ns=new HashSet();
-    ns.add(d);
-    return getMoreMethodCalls(ns, d);
-  }
-
-  private Set getMoreMethodCalls(HashSet found, Descriptor d) {
-    HashSet ns=new HashSet();
-    ns.add(d);
-    found.add(d);
-    Set s=(Set)mapCaller2CalleeSet.get(d);
-    if (s!=null)
-      for(Iterator it=s.iterator(); it.hasNext();) {
-       MethodDescriptor md=(MethodDescriptor)it.next();
-       if( !found.contains(md) ) {
-         ns.addAll(getMoreMethodCalls(found, md));
-       }
-      }
-    return ns;
-  }
-
-  public boolean isCallable(MethodDescriptor md) {
-    return true;
-  }
-
-  /** Returns all methods transitively callable from d */
-
-  public Set getAllMethods(Descriptor d) {
-    HashSet tovisit=new HashSet();
-    tovisit.add(d);
-    HashSet callable=new HashSet();
-    while(!tovisit.isEmpty()) {
-      Descriptor md=(Descriptor)tovisit.iterator().next();
-      tovisit.remove(md);
-      Set s=(Set)mapCaller2CalleeSet.get(md);
-
-      if (s!=null) {
-       for(Iterator it=s.iterator(); it.hasNext();) {
-         MethodDescriptor md2=(MethodDescriptor)it.next();
-         if( !callable.contains(md2) ) {
-           callable.add(md2);
-           tovisit.add(md2);
-         }
-       }
-      }
-    }
-    return callable;
-  }
-  
-  // Returns a set of methods containing SESEs and located at the first   
-  // in transitive call chain starting from d 
-  public Set getFirstReachableMethodContainingSESE(Descriptor d,
-      Set<MethodDescriptor> methodsContainingSESEs) {
-    HashSet tovisit = new HashSet();
-    tovisit.add(d);
-    HashSet callable = new HashSet();
-    while (!tovisit.isEmpty()) {
-      Descriptor md = (Descriptor) tovisit.iterator().next();
-      tovisit.remove(md);
-      Set s = (Set) mapCaller2CalleeSet.get(md);
-
-      if (s != null) {
-        for (Iterator it = s.iterator(); it.hasNext();) {
-          MethodDescriptor md2 = (MethodDescriptor) it.next();
-          if (!callable.contains(md2)) {
-            callable.add(md2);
-            if (!methodsContainingSESEs.contains(md2)) {
-              // if current method has sese, do not need to go down
-              tovisit.add(md2);
-            }
-          }
-        }
-      }
-    }
-//    callable.retainAll(methodsContainingSESEs);
-    return callable;
-  }
-  
-
-  private void buildGraph() {
-    Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
-    while(it.hasNext()) {
-      ClassDescriptor cn=(ClassDescriptor)it.next();
-      Iterator methodit=cn.getMethods();
-      //Iterator through methods
-      while(methodit.hasNext()) {
-       MethodDescriptor md=(MethodDescriptor)methodit.next();
-       analyzeMethod( (Object)md, state.getMethodFlat(md) );
-      }
-    }
-    it=state.getTaskSymbolTable().getDescriptorsIterator();
-    while(it.hasNext()) {
-      TaskDescriptor td=(TaskDescriptor)it.next();
-      analyzeMethod( (Object)td, state.getMethodFlat(td) );
-    }
-  }
-
-  protected void analyzeMethod(Object caller, FlatMethod fm) {
-    HashSet toexplore=new HashSet();
-    toexplore.add(fm);
-    HashSet explored=new HashSet();
-    //look at all the nodes in the flat representation
-    while(!toexplore.isEmpty()) {
-      FlatNode fn=(FlatNode)(toexplore.iterator()).next();
-      toexplore.remove(fn);
-      explored.add(fn);
-      for(int i=0; i<fn.numNext(); i++) {
-       FlatNode fnnext=fn.getNext(i);
-       if (!explored.contains(fnnext))
-         toexplore.add(fnnext);
-      }
-      if (fn.kind()==FKind.FlatCall) {
-       FlatCall fc=(FlatCall)fn;
-       MethodDescriptor calledmethod=fc.getMethod();
-       Set methodsthatcouldbecalled=fc.getThis()==null ? getMethods(calledmethod) :
-                                     getMethods(calledmethod, fc.getThis().getType());
-       
-       // add caller -> callee maps
-       if( !mapCaller2CalleeSet.containsKey(caller) ) {
-         mapCaller2CalleeSet.put(caller, new HashSet() );
-       }
-       ((HashSet)mapCaller2CalleeSet.get(caller)).addAll(methodsthatcouldbecalled);
-
-       // add callee -> caller maps
-       Iterator calleeItr = methodsthatcouldbecalled.iterator();
-       while( calleeItr.hasNext() ) {
-         MethodDescriptor callee = (MethodDescriptor) calleeItr.next();
-         if( !mapCallee2CallerSet.containsKey(callee) ) {
-           mapCallee2CallerSet.put(callee, new HashSet() );
-         }
-         ((HashSet)mapCallee2CallerSet.get(callee)).add(caller);
-       }
-      }
-    }
-  }
-
-
-  public void writeVirtual2ImplemToDot(String graphName)  throws java.io.IOException {
-    HashSet labeledInDot = new HashSet();
-
-    BufferedWriter bw = new BufferedWriter(new FileWriter(graphName+".dot") );
-    bw.write("digraph "+graphName+" {\n");
-    Iterator mapItr =  mapVirtual2ImplementationSet.entrySet().iterator();
-    while( mapItr.hasNext() ) {
-      Map.Entry me        = (Map.Entry)mapItr.next();
-      MethodDescriptor virtual   = (MethodDescriptor) me.getKey();
-      HashSet implemSet = (HashSet)          me.getValue();
-
-      if( !labeledInDot.contains(virtual) ) {
-       labeledInDot.add(virtual);
-       bw.write("  "+virtual.getNum()+"[label=\""+virtual+"\"];\n");
-      }
-
-      Iterator implemItr = implemSet.iterator();
-      while( implemItr.hasNext() ) {
-       Descriptor implem = (Descriptor) implemItr.next();
-
-       if( !labeledInDot.contains(implem) ) {
-         labeledInDot.add(implem);
-         bw.write("  "+implem.getNum()+"[label=\""+implem+"\"];\n");
-       }
-
-       bw.write("  "+virtual.getNum()+"->"+implem.getNum()+";\n");
-      }
-    }
-    bw.write("}\n");
-    bw.close();
-  }
-
-
-  public void writeCaller2CalleesToDot(String graphName)  throws java.io.IOException {
-    // write out the call graph (should be equivalent) by
-    // using the callers mapping
-    HashSet labeledInDot = new HashSet();
-    BufferedWriter bw = new BufferedWriter(new FileWriter(graphName+"byCallers.dot") );
-    bw.write("digraph "+graphName+"byCallers {\n");
-    Iterator mapItr = mapCaller2CalleeSet.entrySet().iterator();
-    while( mapItr.hasNext() ) {
-      Map.Entry me      = (Map.Entry)mapItr.next();
-      Descriptor caller = (Descriptor) me.getKey();
-      HashSet calleeSet = (HashSet)    me.getValue();
-
-      if( !labeledInDot.contains(caller) ) {
-       labeledInDot.add(caller);
-       bw.write("  "+caller.getNum()+"[label=\"" +caller+"\"];\n");
-      }
-
-      Iterator calleeItr = calleeSet.iterator();
-      while( calleeItr.hasNext() ) {
-       MethodDescriptor callee = (MethodDescriptor) calleeItr.next();
-
-       if( !labeledInDot.contains(callee) ) {
-         labeledInDot.add(callee);
-         bw.write("  "+callee.getNum()+"[label=\""+callee+"\"];\n");
-       }
-
-       bw.write("  "+caller.getNum()+"->"+callee.getNum()+";\n");
-      }
-    }
-    bw.write("}\n");
-    bw.close();
-  }
-
-
-  public void writeCallee2CallersToDot(String graphName)  throws java.io.IOException {
-    // each task or method only needs to be labeled once
-    // in a dot file
-    HashSet labeledInDot = new HashSet();
-
-    // write out the call graph using the callees mapping
-    BufferedWriter bw = new BufferedWriter(new FileWriter(graphName+"byCallees.dot") );
-    bw.write("digraph "+graphName+"byCallees {\n");
-    Iterator mapItr = mapCallee2CallerSet.entrySet().iterator();
-    while( mapItr.hasNext() ) {
-      Map.Entry me        = (Map.Entry)mapItr.next();
-      MethodDescriptor callee    = (MethodDescriptor) me.getKey();
-      HashSet callerSet = (HashSet)          me.getValue();
-
-      if( !labeledInDot.contains(callee) ) {
-       labeledInDot.add(callee);
-       bw.write("  "+callee.getNum()+"[label=\""+callee+"\"];\n");
-      }
-
-      Iterator callerItr = callerSet.iterator();
-      while( callerItr.hasNext() ) {
-       Descriptor caller = (Descriptor) callerItr.next();
 
-       if( !labeledInDot.contains(caller) ) {
-         labeledInDot.add(caller);
-         bw.write("  "+caller.getNum()+"[label=\""+caller+"\"];\n");
-       }
 
-       bw.write("  "+caller.getNum()+"->"+callee.getNum()+";\n");
-      }
-    }
-    bw.write("}\n");
-    bw.close();
-  }
-}
+public interface CallGraph {
+  public Set getAllMethods(Descriptor d);
+  public Set getMethods(MethodDescriptor md, TypeDescriptor type);
+  public Set getMethods(MethodDescriptor md);
+  public Set getCallerSet(MethodDescriptor md);
+  public Set getCalleeSet(Descriptor d);
+  public boolean isCallable(MethodDescriptor md);
+  public Set getMethodCalls(Descriptor d);
+  public Set getFirstReachableMethodContainingSESE(Descriptor d, Set<MethodDescriptor> methodsContainingSESEs);
+}
\ No newline at end of file
index c7acbbe7fa02618bdb2a713bc2c64e658949aa66..d32cf463fa7a802b149a5230cc8862beab659e2e 100644 (file)
@@ -13,7 +13,7 @@ import IR.TypeUtil;
 import java.util.*;
 import java.io.*;
 
-public class JavaCallGraph extends CallGraph {
+public class JavaCallGraph extends BaseCallGraph {
   TypeUtil tu;
   HashSet discovered;
 
index 2009f545fc2c4c2f57f4fccc576063ebd964541d..1374e1f44bc701fea12d6761f565ef9ca67a95d6 100644 (file)
@@ -34,6 +34,7 @@ import Analysis.TaskStateAnalysis.TaskAnalysis;
 import Analysis.TaskStateAnalysis.TaskTagAnalysis;
 import Analysis.TaskStateAnalysis.TaskGraph;
 import Analysis.CallGraph.CallGraph;
+import Analysis.CallGraph.BaseCallGraph;
 import Analysis.CallGraph.JavaCallGraph;
 import Analysis.TaskStateAnalysis.FEdge;
 import Analysis.TaskStateAnalysis.FlagState;
@@ -66,7 +67,7 @@ public class Main {
   public static void main(String args[]) throws Exception {
     String ClassLibraryPrefix="./ClassLibrary/";
     State state=new State();
-    Vector sourcefiles=new Vector();
+    Vector<String> sourcefiles=new Vector<String>();
     State.initTimer();
     state.classpath.add(".");
 
@@ -417,7 +418,7 @@ public class Main {
     SemanticCheck sc=new SemanticCheck(state,tu);
 
     for(int i=0;i<sourcefiles.size();i++)
-      loadClass(state, bir,(String)sourcefiles.get(i));
+      loadClass(state, bir, sourcefiles.get(i));
 
     //Stuff the runtime wants to see
 
@@ -452,7 +453,7 @@ public class Main {
       }
     }
 
-    CallGraph callgraph=state.TASK?new CallGraph(state, tu):new JavaCallGraph(state, tu);
+    CallGraph callgraph=state.TASK?new BaseCallGraph(state, tu):new JavaCallGraph(state, tu);
     
     // SSJava
     if(state.SSJAVA){