1 package Analysis.Disjoint;
10 //////////////////////////////////////////////
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.
17 //////////////////////////////////////////////
19 public class StateMachineForEffects {
20 public final static FlatNode startNode=new FlatNop();
21 protected HashMap<Pair<Alloc, FieldDescriptor>, Integer> effectsMap;
23 // states in the machine are uniquely identified
24 // by a flat node (program point)
25 protected Hashtable<FlatNode, SMFEState> fn2state;
27 //TODO Jim! Jim! Give me the weakly connected group number here!
28 protected Hashtable<FlatNode, Integer> fn2weaklyConnectedGroupID;
30 protected SMFEState initialState;
31 protected FlatNode fn;
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;
45 public StateMachineForEffects(FlatNode fnInitial) {
46 fn2state = new Hashtable<FlatNode, SMFEState>();
47 effectsMap = new HashMap<Pair<Alloc, FieldDescriptor>, Integer>();
48 initialState = getState(startNode);
50 possiblyEvilEffects = new HashSet<Effect>();
53 public Set<SMFEState> getStates() {
54 HashSet<SMFEState> set=new HashSet<SMFEState>();
55 set.addAll(fn2state.values());
59 public FlatNode getStallorSESE() {
63 public boolean isEmpty() {
64 for(FlatNode fn : fn2state.keySet()) {
65 SMFEState state=fn2state.get(fn);
66 if (!state.getConflicts().isEmpty())
72 public int getEffects(Alloc affectedNode, FieldDescriptor fd) {
73 Integer type=effectsMap.get(new Pair<Alloc, FieldDescriptor>(affectedNode, fd));
77 return type.intValue();
80 public void addEffect(FlatNode fnState, Effect e) {
83 SMFEState state = getState(fnState);
85 Pair<Alloc, FieldDescriptor> p=new Pair<Alloc, FieldDescriptor>(e.getAffectedAllocSite(), e.getField());
87 if (!effectsMap.containsKey(p))
88 effectsMap.put(p, new Integer(type));
90 effectsMap.put(p, new Integer(type|effectsMap.get(p).intValue()));
93 public void addTransition(FlatNode fnFrom,
99 assert fn2state.containsKey(fnFrom);
100 SMFEState stateFrom = getState(fnFrom);
101 SMFEState stateTo = getState(fnTo);
103 stateFrom.addTransition(e, stateTo);
106 public SMFEState getInitialState() {
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);
120 public Integer getWeaklyConnectedGroupID(FlatNode fn) {
121 //TODO stubby stubby!
126 public void addPossiblyEvilEffect(Effect e) {
127 possiblyEvilEffects.add(e);
130 public Set<Effect> getPossiblyEvilEffects() {
131 return possiblyEvilEffects;
135 public void writeAsDOT(String graphName) {
136 graphName = graphName.replaceAll("[\\W]", "");
140 new BufferedWriter(new FileWriter(graphName+".dot") );
142 bw.write("digraph "+graphName+" {\n");
144 Iterator<FlatNode> fnItr = fn2state.keySet().iterator();
145 while( fnItr.hasNext() ) {
146 SMFEState state = fn2state.get(fnItr.next() );
147 bw.write(state.toStringDOT()+"\n");
153 } catch( IOException e ) {
154 throw new Error("Error writing out DOT graph "+graphName);