1 package Analysis.TaskStateAnalysis;
2 import Analysis.TaskStateAnalysis.*;
10 /** This class is used to hold the flag states that a class in the Bristlecone
11 * program can exist in, during runtime.
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;
19 private static int nodeid=0;
21 private final HashSet flagstate;
22 private final ClassDescriptor cd;
23 private final Hashtable<TagDescriptor,Integer> tags;
24 private boolean issourcenode;
27 private boolean marked=false;
31 * Creates a new flagstate with all flags set to false.
32 * @param cd ClassDescriptor
34 public FlagState(ClassDescriptor cd) {
35 this.flagstate=new HashSet();
37 this.tags=new Hashtable<TagDescriptor,Integer>();
38 this.uid=FlagState.nodeid++;
39 this.issourcenode=false;
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
48 private FlagState(HashSet flagstate, ClassDescriptor cd,Hashtable<TagDescriptor,Integer> tags) {
49 this.flagstate=flagstate;
52 this.uid=FlagState.nodeid++;
53 this.issourcenode=false;
61 public boolean isMarked() {
65 public void doUnmarking() {
69 public void doMarking() {
74 * @param fd FlagDescriptor
75 * @return true if the flagstate contains fd else false.
77 public boolean get(FlagDescriptor fd) {
78 return flagstate.contains(fd);
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).
85 public boolean isSourceNode(){
89 /** Sets the flagstate as a source node.
91 public void setAsSourceNode(){
94 this.tasks=new Vector();
98 public void addAllocatingTask(TaskDescriptor task){
102 public Vector getAllocatingTasks(){
107 public String toString() {
108 return cd.toString()+getTextLabel();
111 /** @return Iterator over the flags in the flagstate.
114 public Iterator getFlags() {
115 return flagstate.iterator();
118 public int numFlags(){
119 return flagstate.size();
122 public FlagState[] setTag(TagDescriptor tag){
123 HashSet newset1=(HashSet)flagstate.clone();
124 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
126 if (tags.containsKey(tag)){
127 //Code could try to remove flag that doesn't exist
129 switch (tags.get(tag).intValue()){
131 newtags1.put(tag,new Integer(MULTITAGS));
132 return new FlagState[] {this, new FlagState(newset1, cd, newtags1)};
134 return new FlagState[] {this};
139 newtags1.put(tag,new Integer(ONETAG));
140 return new FlagState[] {new FlagState(newset1,cd,newtags1)};
144 public int getTagCount(String tagtype){
145 for (Enumeration en=getTags();en.hasMoreElements();){
146 TagDescriptor td=(TagDescriptor)en.nextElement();
147 if (tagtype.equals(td.getSymbol()))
148 return tags.get(td).intValue(); //returns either ONETAG or MULTITAG
153 public FlagState[] clearTag(TagDescriptor tag){
154 if (tags.containsKey(tag)){
155 switch(tags.get(tag).intValue()){
157 HashSet newset=(HashSet)flagstate.clone();
158 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
160 return new FlagState[]{new FlagState(newset,cd,newtags)};
163 //two possibilities - count remains 2 or becomes 1
165 HashSet newset1=(HashSet)flagstate.clone();
166 Hashtable<TagDescriptor,Integer> newtags1=(Hashtable<TagDescriptor,Integer>)tags.clone();
169 HashSet newset2=(HashSet)flagstate.clone();
170 Hashtable<TagDescriptor,Integer> newtags2=(Hashtable<TagDescriptor,Integer>)tags.clone();
171 newtags1.put(tag,new Integer(ONETAG));
172 return new FlagState[] {new FlagState(newset1, cd, newtags2),
173 new FlagState(newset2, cd, newtags2)};
178 throw new Error("Invalid Operation: Can not clear a tag that doesn't exist.");
182 /** Creates a string description of the flagstate
183 * e.g. a flagstate with five flags could look like 01001
184 * @param flags an array of flagdescriptors.
185 * @return string representation of the flagstate.
187 public String toString(FlagDescriptor[] flags)
189 StringBuffer sb = new StringBuffer(flagstate.size());
190 for(int i=0;i < flags.length; i++)
198 return new String(sb);
202 * @return returns the classdescriptor of the flagstate.
205 public ClassDescriptor getClassDescriptor(){
209 /** Sets the status of a specific flag in a flagstate after cloning it.
210 * @param fd FlagDescriptor of the flag whose status is being set.
211 * @param status boolean value
212 * @return the new flagstate with <CODE>fd</CODE> set to <CODE>status</CODE>.
215 public FlagState setFlag(FlagDescriptor fd, boolean status) {
216 HashSet newset=(HashSet) flagstate.clone();
217 Hashtable<TagDescriptor,Integer> newtags=(Hashtable<TagDescriptor,Integer>)tags.clone();
220 else if (newset.contains(fd)){
224 return new FlagState(newset, cd, newtags);
227 /** Tests for equality of two flagstate objects.
230 public boolean equals(Object o) {
231 if (o instanceof FlagState) {
232 FlagState fs=(FlagState)o;
235 return (fs.flagstate.equals(flagstate) & fs.tags.equals(tags));
240 public int hashCode() {
241 return cd.hashCode()^flagstate.hashCode()^tags.hashCode();
244 public String getLabel() {
251 public String getTextLabel() {
253 for(Iterator it=getFlags();it.hasNext();) {
254 FlagDescriptor fd=(FlagDescriptor) it.next();
258 label+=", "+fd.toString();
260 for (Enumeration en_tags=getTags();en_tags.hasMoreElements();){
261 TagDescriptor td=(TagDescriptor)en_tags.nextElement();
262 switch (tags.get(td).intValue()){
265 label=td.toString()+"(1)";
267 label+=", "+td.toString()+"(1)";
271 label=td.toString()+"(n)";
273 label+=", "+td.toString()+"(n)";
284 public Enumeration getTags(){