Create analysis model for string literals in disjointness analysis that supports...
[IRC.git] / Robust / src / Analysis / Disjoint / StateMachineForEffects.java
index f12aa2d618cc03a9f69de5785e236be68d22215b..fea9044a87eef8983b7ddd3e0b39e3305e7a2fb7 100644 (file)
@@ -5,6 +5,7 @@ import java.io.*;
 
 import IR.*;
 import IR.Flat.*;
+import Util.Pair;
 
 //////////////////////////////////////////////
 //
@@ -16,74 +17,141 @@ import IR.Flat.*;
 //////////////////////////////////////////////
 
 public class StateMachineForEffects {
+  public final static FlatNode startNode=new FlatNop();
+  protected HashMap<Pair<Alloc, FieldDescriptor>, Integer> effectsMap;
 
-  // states in the machine are uniquely identified 
+  // states in the machine are uniquely identified
   // by a flat node (program point)
   protected Hashtable<FlatNode, SMFEState> fn2state;
 
+  //TODO Jim! Jim! Give me the weakly connected group number here!
+  protected Hashtable<FlatNode, Integer> fn2weaklyConnectedGroupID;
+
   protected SMFEState initialState;
+  protected FlatNode fn;
+  protected int id=0;
+
+  // We have a situation in which a task can start executing
+  // and "evil-ly" destroy the paths to all the objects it will
+  // access as it goes along.  If this is the case, a traverser
+  // should know which effects these are, and if the traverser
+  // is ever running and detects that the task is also running,
+  // it should not continue (and therefore hold up any tasks that
+  // might come later, because now we might never be able to find
+  // the effects that should block later tasks).  Should be rare!
+  protected Set<Effect> possiblyEvilEffects;
 
 
-  public StateMachineForEffects( FlatNode fnInitial ) {
+  public StateMachineForEffects(FlatNode fnInitial) {
     fn2state = new Hashtable<FlatNode, SMFEState>();
+    effectsMap = new HashMap<Pair<Alloc, FieldDescriptor>, Integer>();
+    initialState = getState(startNode);
+    this.fn=fnInitial;
+    possiblyEvilEffects = new HashSet<Effect>();
+  }
+
+  public Set<SMFEState> getStates() {
+    HashSet<SMFEState> set=new HashSet<SMFEState>();
+    set.addAll(fn2state.values());
+    return set;
+  }
 
-    initialState = getState( fnInitial );
+  public FlatNode getStallorSESE() {
+    return fn;
   }
 
-  public void addEffect( FlatNode fnState,
-                         Effect e ) {
+  public boolean isEmpty() {
+    for(FlatNode fn : fn2state.keySet()) {
+      SMFEState state=fn2state.get(fn);
+      if (!state.getConflicts().isEmpty())
+        return false;
+    }
+    return true;
+  }
+
+  public int getEffects(Alloc affectedNode, FieldDescriptor fd) {
+    Integer type=effectsMap.get(new Pair<Alloc, FieldDescriptor>(affectedNode, fd));
+    if (type==null)
+      return 0;
+    else
+      return type.intValue();
+  }
 
-    SMFEState state = getState( fnState );
-    state.addEffect( e );
+  public void addEffect(FlatNode fnState, Effect e) {
+    if (fnState==null)
+      fnState=startNode;
+    SMFEState state = getState(fnState);
+    state.addEffect(e);
+    Pair<Alloc, FieldDescriptor> p=new Pair<Alloc, FieldDescriptor>(e.getAffectedAllocSite(), e.getField());
+    int type=e.getType();
+    if (!effectsMap.containsKey(p))
+      effectsMap.put(p, new Integer(type));
+    else
+      effectsMap.put(p, new Integer(type|effectsMap.get(p).intValue()));
   }
 
-  public void addTransition( FlatNode fnFrom,
-                             FlatNode fnTo,
-                             Effect e ) {
+  public void addTransition(FlatNode fnFrom,
+                            FlatNode fnTo,
+                            Effect e) {
+    if (fnFrom==null)
+      fnFrom=startNode;
 
-    assert fn2state.containsKey( fnFrom );
-    SMFEState stateFrom = getState( fnFrom );
-    SMFEState stateTo   = getState( fnTo );
+    assert fn2state.containsKey(fnFrom);
+    SMFEState stateFrom = getState(fnFrom);
+    SMFEState stateTo   = getState(fnTo);
 
-    stateFrom.addTransition( e, stateTo );
+    stateFrom.addTransition(e, stateTo);
   }
 
-  public SMFEState getIntialState() {
+  public SMFEState getInitialState() {
     return initialState;
   }
 
 
-  protected SMFEState getState( FlatNode fn ) {
-    SMFEState state = fn2state.get( fn );
+  protected SMFEState getState(FlatNode fn) {
+    SMFEState state = fn2state.get(fn);
     if( state == null ) {
-      state = new SMFEState( fn );
-      fn2state.put( fn, state );
+      state = new SMFEState(fn,id++);
+      fn2state.put(fn, state);
     }
     return state;
   }
 
+  public Integer getWeaklyConnectedGroupID(FlatNode fn) {
+    //TODO stubby stubby!
+    return 0;
+  }
+
+
+  public void addPossiblyEvilEffect(Effect e) {
+    possiblyEvilEffects.add(e);
+  }
+
+  public Set<Effect> getPossiblyEvilEffects() {
+    return possiblyEvilEffects;
+  }
 
-  public void writeAsDOT( String graphName ) {
-    //String graphName = initialState.getID().toString();
-    graphName = graphName.replaceAll( "[\\W]", "" );
+
+  public void writeAsDOT(String graphName) {
+    graphName = graphName.replaceAll("[\\W]", "");
 
     try {
-      BufferedWriter bw = 
-        new BufferedWriter( new FileWriter( graphName+".dot" ) );
+      BufferedWriter bw =
+        new BufferedWriter(new FileWriter(graphName+".dot") );
 
-      bw.write( "digraph "+graphName+" {\n" );
+      bw.write("digraph "+graphName+" {\n");
 
       Iterator<FlatNode> fnItr = fn2state.keySet().iterator();
       while( fnItr.hasNext() ) {
-        SMFEState state = fn2state.get( fnItr.next() );
-        bw.write( state.toStringDOT()+"\n" );
+        SMFEState state = fn2state.get(fnItr.next() );
+        bw.write(state.toStringDOT()+"\n");
       }
 
-      bw.write( "}\n" );
+      bw.write("}\n");
       bw.close();
-      
+
     } catch( IOException e ) {
-      throw new Error( "Error writing out DOT graph "+graphName );
+      throw new Error("Error writing out DOT graph "+graphName);
     }
   }