changes
[IRC.git] / Robust / src / Analysis / TaskStateAnalysis / FlagState.java
1 package Analysis.TaskStateAnalysis;
2 import Analysis.TaskStateAnalysis.*;
3 import IR.*;
4 import IR.Tree.*;
5 import IR.Flat.*;
6 import java.util.*;
7 import java.io.*;
8 import Util.GraphNode;
9
10 /** This class is used to hold the flag states that a class in the Bristlecone 
11  *  program can exist in, during runtime.
12  */
13 public class FlagState extends GraphNode {
14     public static final int ONETAG=1;
15     public static final int NOTAGS=0;
16     public static final int MULTITAGS=-1;
17     
18     private int uid;
19     private static int nodeid=0;
20
21     private final HashSet flagstate;
22     private final ClassDescriptor cd;
23     private final Hashtable<TagDescriptor,Integer> tags;
24     private boolean issourcenode;
25     private Vector tasks;
26
27     private boolean marked=false;
28     
29
30     /** Class constructor
31      *  Creates a new flagstate with all flags set to false.
32      *  @param cd ClassDescriptor
33      */
34     public FlagState(ClassDescriptor cd) {
35         this.flagstate=new HashSet();
36         this.cd=cd;
37         this.tags=new Hashtable<TagDescriptor,Integer>();
38         this.uid=FlagState.nodeid++;
39         this.issourcenode=false;
40     }
41
42     /** Class constructor
43      *  Creates a new flagstate with flags set according to the HashSet.
44      *  If the flag exists in the hashset, it's set to true else set to false.
45      *  @param cd ClassDescriptor
46      *  @param flagstate a <CODE>HashSet</CODE> containing FlagDescriptors
47      */
48     private FlagState(HashSet flagstate, ClassDescriptor cd,Hashtable<TagDescriptor,Integer> tags) {
49         this.flagstate=flagstate;
50         this.cd=cd;
51         this.tags=tags;
52         this.uid=FlagState.nodeid++;
53         this.issourcenode=false;
54         
55     }
56    
57     public int getuid() {
58         return uid;
59     }
60
61     public boolean isMarked() {
62         return marked;
63     }
64
65     public void doUnmarking() {
66         marked = false;
67     }
68
69     public void doMarking() {
70         marked = true;
71     }
72             
73     /** Accessor method
74       *  @param fd FlagDescriptor
75       *  @return true if the flagstate contains fd else false.
76       */
77     public boolean get(FlagDescriptor fd) {
78         return flagstate.contains(fd);
79     }
80     
81     /** Checks if the flagstate is a source node. 
82      *  @return true if the flagstate is a sourcenode(i.e. Is the product of an allocation site).
83      */
84       
85     public boolean isSourceNode(){
86             return issourcenode;
87         }
88         
89         /**  Sets the flagstate as a source node. 
90      */
91         public void setAsSourceNode(){
92                 if(!issourcenode){
93                         issourcenode=true;
94                         this.tasks=new Vector();
95                 }
96         }
97         
98         public void addAllocatingTask(TaskDescriptor task){
99                 tasks.add(task);
100         }
101
102         public Vector getAllocatingTasks(){
103                 return tasks;
104         }
105                 
106     
107     public String toString() {
108         return cd.toString()+getTextLabel();
109     }
110
111     /** @return Iterator over the flags in the flagstate.
112      */
113      
114     public Iterator getFlags() {
115         return flagstate.iterator();
116     }
117     
118     public FlagState[] setTag(TagDescriptor tag){
119         HashSet newset1=(HashSet)flagstate.clone();
120         Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
121             
122         if (tags.containsKey(tag)){
123             //Code could try to remove flag that doesn't exist
124             
125             switch (tags.get(tag).intValue()){
126             case ONETAG:
127                 newtags1.put(tag,new Integer(MULTITAGS));
128                 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
129             case MULTITAGS:
130                 return new FlagState[] {this};
131             default:
132                 throw new Error();
133             }
134         } else {
135             newtags1.put(tag,new Integer(ONETAG));
136             return new FlagState[] {new FlagState(newset1,cd,newtags1)};
137         }
138     }
139
140     public int getTagCount(String tagtype){
141         for (Enumeration en=getTags();en.hasMoreElements();){
142             TagDescriptor td=(TagDescriptor)en.nextElement();
143             if (tagtype.equals(td.getSymbol()))
144                 return tags.get(td).intValue();   //returns either ONETAG or MULTITAG
145         }
146         return NOTAGS;
147     }
148     
149     public FlagState[] clearTag(TagDescriptor tag){
150         if (tags.containsKey(tag)){
151             switch(tags.get(tag).intValue()){
152             case ONETAG:
153                 HashSet newset=(HashSet)flagstate.clone();
154                 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
155                 newtags.remove(tag);
156                 return new FlagState[]{new FlagState(newset,cd,newtags)};
157                 
158             case MULTITAGS:
159                 //two possibilities - count remains 2 or becomes 1
160                 //2 case
161                 HashSet newset1=(HashSet)flagstate.clone();
162                 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
163
164                 //1 case
165                 HashSet newset2=(HashSet)flagstate.clone();
166                 Hashtable<TagDescriptor,Integer> newtags2=(Hashtable<TagDescriptor,Integer>)tags.clone();
167                 newtags1.put(tag,new Integer(ONETAG));
168                 return new FlagState[] {new FlagState(newset1, cd, newtags2),
169                                         new FlagState(newset2, cd, newtags2)};
170             default:
171                 throw new Error();
172             }
173         } else {
174             throw new Error("Invalid Operation: Can not clear a tag that doesn't exist.");
175         }
176     }
177     
178     /** Creates a string description of the flagstate
179      *  e.g.  a flagstate with five flags could look like 01001
180      *  @param flags an array of flagdescriptors.
181      *  @return string representation of the flagstate.
182      */
183         public String toString(FlagDescriptor[] flags)
184         {
185                 StringBuffer sb = new StringBuffer(flagstate.size());
186                 for(int i=0;i < flags.length; i++)
187                 {
188                         if (get(flags[i]))
189                                 sb.append(1);
190                         else
191                                 sb.append(0);
192                 }
193                         
194                 return new String(sb);
195         }
196
197         /** Accessor method
198          *  @return returns the classdescriptor of the flagstate.
199          */
200          
201     public ClassDescriptor getClassDescriptor(){
202         return cd;
203     }
204
205         /** Sets the status of a specific flag in a flagstate after cloning it.
206          *  @param      fd FlagDescriptor of the flag whose status is being set.
207          *  @param  status boolean value
208          *  @return the new flagstate with <CODE>fd</CODE> set to <CODE>status</CODE>.
209          */
210          
211     public FlagState setFlag(FlagDescriptor fd, boolean status) {
212         HashSet newset=(HashSet) flagstate.clone();
213         Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
214         if (status)
215             newset.add(fd);
216         else if (newset.contains(fd)){
217             newset.remove(fd);
218         }
219         
220         return new FlagState(newset, cd, newtags);
221     }
222     
223     /** Tests for equality of two flagstate objects.
224     */
225     
226     public boolean equals(Object o) {
227         if (o instanceof FlagState) {
228             FlagState fs=(FlagState)o;
229             if (fs.cd!=cd)
230                 return false;
231             return (fs.flagstate.equals(flagstate) & fs.tags.equals(tags));
232         }
233         return false;
234     }
235
236     public int hashCode() {
237         return cd.hashCode()^flagstate.hashCode()^tags.hashCode();
238     }
239
240     public String getLabel() {
241         return "N"+uid;
242     }
243     
244     
245         
246
247     public String getTextLabel() {
248         String label=null;
249         for(Iterator it=getFlags();it.hasNext();) {
250             FlagDescriptor fd=(FlagDescriptor) it.next();
251             if (label==null)
252                 label=fd.toString();
253             else
254                 label+=", "+fd.toString();
255         }
256         for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){
257                 TagDescriptor td=(TagDescriptor)en_tags.nextElement();
258                 switch (tags.get(td).intValue()){
259                 case ONETAG:
260                     if (label==null)
261                         label=td.toString()+"(1)";
262                     else
263                         label+=", "+td.toString()+"(1)";
264                     break;
265                 case MULTITAGS:
266                     if (label==null)
267                         label=td.toString()+"(n)";
268                     else
269                         label+=", "+td.toString()+"(n)";
270                     break;
271                 default:
272                     break;
273                 }
274         }
275         if (label==null)
276             return " ";
277         return label;
278     }
279     
280     public Enumeration getTags(){
281             return tags.keys();
282     }
283 }