Fix tabbing.... Please fix your editors so they do tabbing correctly!!! (Spaces...
[IRC.git] / Robust / src / Analysis / Disjoint / StateMachineForEffects.java
1 package Analysis.Disjoint;
2
3 import java.util.*;
4 import java.io.*;
5
6 import IR.*;
7 import IR.Flat.*;
8 import Util.Pair;
9
10 //////////////////////////////////////////////
11 //
12 //  StateMachineForEffects describes an intial
13 //  state and the effect transtions a DFJ
14 //  traverser should make from the current state
15 //  when searching for possible runtime conflicts.
16 //
17 //////////////////////////////////////////////
18
19 public class StateMachineForEffects {
20   public final static FlatNode startNode=new FlatNop();
21   protected HashMap<Pair<Alloc, FieldDescriptor>, Integer> effectsMap;
22
23   // states in the machine are uniquely identified
24   // by a flat node (program point)
25   protected Hashtable<FlatNode, SMFEState> fn2state;
26
27   //TODO Jim! Jim! Give me the weakly connected group number here!
28   protected Hashtable<FlatNode, Integer> fn2weaklyConnectedGroupID;
29
30   protected SMFEState initialState;
31   protected FlatNode fn;
32   protected int id=0;
33
34   // We have a situation in which a task can start executing
35   // and "evil-ly" destroy the paths to all the objects it will
36   // access as it goes along.  If this is the case, a traverser
37   // should know which effects these are, and if the traverser
38   // is ever running and detects that the task is also running,
39   // it should not continue (and therefore hold up any tasks that
40   // might come later, because now we might never be able to find
41   // the effects that should block later tasks).  Should be rare!
42   protected Set<Effect> possiblyEvilEffects;
43
44
45   public StateMachineForEffects(FlatNode fnInitial) {
46     fn2state = new Hashtable<FlatNode, SMFEState>();
47     effectsMap = new HashMap<Pair<Alloc, FieldDescriptor>, Integer>();
48     initialState = getState(startNode);
49     this.fn=fnInitial;
50     possiblyEvilEffects = new HashSet<Effect>();
51   }
52
53   public Set<SMFEState> getStates() {
54     HashSet<SMFEState> set=new HashSet<SMFEState>();
55     set.addAll(fn2state.values());
56     return set;
57   }
58
59   public FlatNode getStallorSESE() {
60     return fn;
61   }
62
63   public boolean isEmpty() {
64     for(FlatNode fn : fn2state.keySet()) {
65       SMFEState state=fn2state.get(fn);
66       if (!state.getConflicts().isEmpty())
67         return false;
68     }
69     return true;
70   }
71
72   public int getEffects(Alloc affectedNode, FieldDescriptor fd) {
73     Integer type=effectsMap.get(new Pair<Alloc, FieldDescriptor>(affectedNode, fd));
74     if (type==null)
75       return 0;
76     else
77       return type.intValue();
78   }
79
80   public void addEffect(FlatNode fnState, Effect e) {
81     if (fnState==null)
82       fnState=startNode;
83     SMFEState state = getState(fnState);
84     state.addEffect(e);
85     Pair<Alloc, FieldDescriptor> p=new Pair<Alloc, FieldDescriptor>(e.getAffectedAllocSite(), e.getField());
86     int type=e.getType();
87     if (!effectsMap.containsKey(p))
88       effectsMap.put(p, new Integer(type));
89     else
90       effectsMap.put(p, new Integer(type|effectsMap.get(p).intValue()));
91   }
92
93   public void addTransition(FlatNode fnFrom,
94                             FlatNode fnTo,
95                             Effect e) {
96     if (fnFrom==null)
97       fnFrom=startNode;
98
99     assert fn2state.containsKey(fnFrom);
100     SMFEState stateFrom = getState(fnFrom);
101     SMFEState stateTo   = getState(fnTo);
102
103     stateFrom.addTransition(e, stateTo);
104   }
105
106   public SMFEState getInitialState() {
107     return initialState;
108   }
109
110
111   protected SMFEState getState(FlatNode fn) {
112     SMFEState state = fn2state.get(fn);
113     if( state == null ) {
114       state = new SMFEState(fn,id++);
115       fn2state.put(fn, state);
116     }
117     return state;
118   }
119
120   public Integer getWeaklyConnectedGroupID(FlatNode fn) {
121     //TODO stubby stubby!
122     return 0;
123   }
124
125
126   public void addPossiblyEvilEffect(Effect e) {
127     possiblyEvilEffects.add(e);
128   }
129
130   public Set<Effect> getPossiblyEvilEffects() {
131     return possiblyEvilEffects;
132   }
133
134
135   public void writeAsDOT(String graphName) {
136     graphName = graphName.replaceAll("[\\W]", "");
137
138     try {
139       BufferedWriter bw =
140         new BufferedWriter(new FileWriter(graphName+".dot") );
141
142       bw.write("digraph "+graphName+" {\n");
143
144       Iterator<FlatNode> fnItr = fn2state.keySet().iterator();
145       while( fnItr.hasNext() ) {
146         SMFEState state = fn2state.get(fnItr.next() );
147         bw.write(state.toStringDOT()+"\n");
148       }
149
150       bw.write("}\n");
151       bw.close();
152
153     } catch( IOException e ) {
154       throw new Error("Error writing out DOT graph "+graphName);
155     }
156   }
157
158 }