1 package Analysis.TaskStateAnalysis;
7 import java.io.FileWriter;
8 import java.io.FileOutputStream;
10 public class TaskTagAnalysis {
12 TagAnalysis taganalysis;
15 HashSet<TagState> toprocess;
16 Hashtable<TaskDescriptor, TaskQueue> tasktable;
23 public TaskTagAnalysis(State state, TagAnalysis taganalysis) {
25 this.typeutil=new TypeUtil(state);
26 this.taganalysis=taganalysis;
27 this.flaginfo=new FlagInfo(state);
28 this.toprocess=new HashSet<TagState>();
29 this.tasktable=new Hashtable<TaskDescriptor, TaskQueue>();
30 for(Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();taskit.hasNext();) {
31 TaskDescriptor td=(TaskDescriptor)taskit.next();
32 tasktable.put(td, new TaskQueue(td));
36 private void doAnalysis() {
37 toprocess.add(createInitialState());
38 while(!toprocess.isEmpty()) {
39 TagState ts=toprocess.iterator().next();
41 //Loop through each task
42 for(Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();taskit.hasNext();) {
43 TaskDescriptor td=(TaskDescriptor)taskit.next();
44 TaskQueue tq=tasktable.get(td);
45 processTask(td, tq, ts);
50 private void processTask(TaskDescriptor td, TaskQueue tq, TagState ts) {
51 Set<FlagState> flagset=ts.getFS();
52 for(Iterator<FlagState> fsit=flagset.iterator();fsit.hasNext();) {
53 FlagState fs=fsit.next();
54 FlagTagState fts=new FlagTagState(ts, fs);
55 for(int i=0;i<td.numParameters();i++) {
56 if (canEnqueue(td, i, fs)) {
57 TaskQueueIterator tqi=tq.enqueue(i, fts);
58 while(tqi.hasNext()) {
67 private void processBinding(TaskQueueIterator tqi) {
68 TaskBinding tb=new TaskBinding(tqi);
75 private Hashtable<TempDescriptor, Wrapper> computeInitialState(Hashtable<FlatNode, Hashtable<TempDescriptor, Wrapper>> maintable, FlatNode fn) {
76 Hashtable<TempDescriptor, Wrapper> table=new Hashtable<TempDescriptor, Wrapper>();
77 Hashtable<TagWrapper,TagWrapper> tagtable=new Hashtable<TagWrapper, TagWrapper>();
78 for(int i=0;i<fn.numPrev();i++) {
79 FlatNode fnprev=fn.getPrev(i);
80 Hashtable<TempDescriptor, Wrapper> prevtable=maintable.get(fn);
82 //Iterator through the Tags
83 for(Iterator<TempDescriptor> tmpit=prevtable.keySet().iterator();tmpit.hasNext();) {
84 TempDescriptor tmp=tmpit.next();
85 Wrapper prevtag=prevtable.get(tmp);
86 if (prevtag instanceof ObjWrapper)
88 if (table.containsKey(tmp)) {
90 TagWrapper currtag=(TagWrapper) table.get(tmp);
91 tagtable.put((TagWrapper)prevtag, currtag);
92 assert(currtag.initts.equals(((TagWrapper)prevtag).initts));
93 for(Iterator<TagState> tagit=((TagWrapper)prevtag).ts.iterator();tagit.hasNext();) {
94 TagState tag=tagit.next();
95 if (!currtag.ts.contains(tag)) {
100 TagWrapper clonetag=prevtag.clone();
101 tagtable.put(prevtag, clonetag);
102 table.put(tmp, clonetag);
106 //Iterator through the Objects
107 for(Iterator<TempDescriptor> tmpit=prevtable.keySet().iterator();tmpit.hasNext();) {
108 TempDescriptor tmp=tmpit.next();
109 Wrapper obj=prevtable.get(tmp);
110 if (obj instanceof TagWrapper)
112 ObjWrapper prevobj=(ObjWrapper)obj;
113 if (!table.containsKey(tmp)) {
115 ObjWrapper newobj=new ObjWrapper();
116 newobj.initfs=prevobj.initfs;
117 table.put(tmp, newobj);
119 ObjWrapper currobj=(ObjWrapper) table.get(tmp);
120 assert(currobj.initfs.equals(prevobj.initfs));
121 for(Iterator<TagWrapper> tagit=prevobj.tags.iterator();tagit.hasNext();) {
122 TagWrapper tprev=tagit.next();
123 TagWrapper t=tagtable.get(tprev);
126 for(Iterator<FlagState> flagit=prevobj.fs.iterator();flagit.hasNext();) {
127 FlagState fs=flagit.nexT();
135 private void processFlatFlag(FlatFlagActionNode fn, Hashtable<TempDescriptor, Wrapper> table) {
136 if (fn.getTaskType()==FlatFlagActionNode.PRE) {
137 throw new Error("Unsupported");
138 } else if (fn.getTaskType()==FlatFlagActionNode.TASKEXIT) {
139 evalTaskExitNode(fn, table);
141 } else if (fn.getTaskType()==FlatFlagActionNode.NEW) {
145 private void setFlag(ObjWrapper ow, FlagDescriptor fd, boolean value) {
146 HashSet<FlagState> newstate=new HashSet<FlagState>();
147 Hastable<FlagState, FlagState> flagmap=new Hashtable<FlagState, FlagState>();
148 for(Iterator<FlagState> flagit=ow.fs.iterator();flagit.hasNext();) {
149 FlagState fs=flagit.next();
150 FlagState fsnew=canonical(fs.setFlag(fd, value));
152 flagmap.put(fs, fsnew);
155 for(Iterator<TagWrapper> tagit=ow.tags.iterator();tagit.hasNext();) {
156 TagWrapper tw=tagit.next();
157 HashSet<TagState> newstates=new HashSet<TagState>();
158 for(Iterator<TagState> tgit=tw.ts.iterator();tgit.hasNext();) {
159 TagState ts=tgit.next();
160 for(Iterator<FlagState> flagit=ts.flags.keySet();flagit.hasNext();) {
161 FlagState fs=flagit.next();
162 if (flagmap.containsKey(fs)) {
163 if (flagmap.get(fs).equals(fs)) {
166 TagState tsarray[]=ts.clearFS(fs);
167 //Can do strong update here because these
168 //must be parameter objects...therefore
169 //all possible aliasing relationships are
171 for(int i=0;i<tsarray.length;i++) {
172 newstates.addAll(Arrays.asList(tsarray[i].addnewFS(flagmap.get(fs))));
183 private void setTag(ObjWrapper ow, TagWrapper tw, boolean value) {
188 private void evalTaskExitNode(FlatFlagActionNode fn, Hashtable<TempDescriptor, Wrapper> table) {
189 //Process clears first
190 for(Iterator it_ttp=ffan.getTempTagPairs();it_ttp.hasNext();) {
191 TempTagPair ttp=(TempTagPair)it_ttp.next();
192 TempDescriptor tmp=ttp.getTemp();
193 TempDescriptor tagtmp=ttp.getTagTemp();
194 TagWrapper tagw=(TagWrapper)table.get(tagtmp)
195 boolean newtagstate=fn.getTagChange(ttp);
196 ObjWrapper ow=(ObjWrapper)table.get(tmp);
198 setTag(ow, tagw, newtagstate);
202 for(Iterator it_ttp=ffan.getTempTagPairs();it_ttp.hasNext();) {
203 TempTagPair ttp=(TempTagPair)it_ttp.next();
204 TempDescriptor tmp=ttp.getTemp();
205 TempDescriptor tagtmp=ttp.getTagTemp();
206 TagWrapper tagw=(TagWrapper)table.get(tagtmp)
207 boolean newtagstate=fn.getTagChange(ttp);
208 ObjWrapper ow=(ObjWrapper)table.get(tmp);
210 setTag(ow, tagw, newtagstate);
214 for(Iterator<TempFlagPair> it_tfp=fn.getTempFlagPairs();it_tfp.hasNext();) {
215 TempFlagPair tfp=it_tfp.next();
216 TempDescriptor tmp=tfp.getTemp();
217 FlagDescriptor fd=tfp.getFlag();
218 boolean newflagstate=fn.getFlagChange(tfp);
219 ObjWrapper ow=(ObjWrapper)table.get(tmp);
220 setFlag(ow, fd, newflagstate);
224 private void processFlatTag(FlatTagDeclaration fn, Hashtable<TempDescriptor, Wrapper> table) {
225 TempDescriptor tmp=fn.getDst();
226 if (table.containsKey(tmp)) {
227 recordtagchange(table.get(tmp));
229 TagDescriptor tag=fn.getTag();
230 TagState ts=canonical(new TagState(tag));
231 TagWrapper tw=new TagWrapper(ts);
236 private void processFlatCall(FlatCall fc, Hashtable<TempDescriptor, Wrapper> table) {
240 private void processFlatReturnNode(FlatReturnNode fr, Hashtable<TempDescriptor, Wrapper> table) {
244 private boolean equivalent(Hashtable<TempDescriptor, Wrapper> table1, Hashtable<TempDescriptor, Wrapper> table2) {
245 Hashtable<Wrapper, Wrapper> emap=new Hashtable<Wrapper, Wrapper>;
247 if (table1.keySet().size()!=table2.keySet().size())
250 for(Iterator<TempDescriptor> tmpit=table1.keySet().iterator();tmpit.hasNext();) {
251 TempDescriptor tmp=tmpit.next();
252 if (table2.containsKey(tmp)) {
253 emap.put(table1.get(tmp), table2.get(tmp));
257 for(Iterator<TempDescriptor> tmpit=table1.keySet().iterator();tmpit.hasNext();) {
258 TempDescriptor tmp=tmpit.next();
259 Wrapper w1=table1.get(tmp);
260 Wrapper w2=table2.get(tmp);
261 if (w1 instanceof TagWrapper) {
262 TagWrapper t1=(TagWrapper)w1;
263 TagWrapper t2=(TagWrapper)w2;
264 if (!t1.ts.equals(t2.ts))
268 ObjWrapper t1=(ObjWrapper)w1;
269 ObjWrapper t2=(ObjWrapper)w2;
270 if (!t1.fs.equals(t2.fs))
272 if (t1.tags.size()!=t2.tags.size())
274 for(Iterator<TagWrapper> twit=t1.tags.iterator();twit.hasNext();) {
275 TagWrapper tw1=twit.next();
276 if (!t2.tags.contains(emap.get(tw1)))
284 private void doAnalysis(TaskBinding tb) {
285 TaskDescriptor td=tb.tqi.tq.getTask();
286 FlatMethod fm=state.getMethodFlat(td);
287 Hashtable<FlatNode, Hashtable<TempDescriptor, Wrapper>> wtable=new Hashtable<FlatNode, Hashtable<TempDescriptor, Wrapper>>();
288 wtable.put(fm, buildinittable(tb));
289 HashSet<FlatNode> visited=new HashSet<FlatNode>();
290 HashSet<FlatNode> tovisit=new HashSet<FlatNode>();
291 tovisit.add(fm.getNext(0));
292 while(!tovisit.isEmpty()) {
293 FlatNode fn=tovisit.iterator().next();
296 Hashtable<TempDescriptor, Wrapper> table=computeInitialState(wtable, fn);
298 case FKind.FlatFlagActionNode:
299 processFlatFlag((FlatFlagActionNode)fn, table);
301 case FKind.FlatTagDeclaration:
302 processFlatTag((FlatTagDeclaration)fn, table);
305 processFlatCall((FlatCall)fn, table);
307 case FKind.FlatReturnNode:
308 processFlatReturnNode((FlatReturn)fn, table);
313 if (!equivalent(table, wtable.get(fn))) {
314 wtable.put(fn, table);
315 for(int i=0;i<fn.numNext();i++) {
316 tovisit.add(fn.getNext(i));
319 for(int i=0;i<fn.numNext();i++) {
320 if (!visited.contains(fn.getNext(i)))
321 tovisit.add(fn.getNext(i));
328 private Hashtable<TempDescriptor, Wrapper> buildinittable(TaskBinding tb, FlatMethod fm) {
329 Hashtable<TempDescriptor, Wrapper> table=new Hashtable<TempDescriptor, Wrapper>();
330 Vector<TempDescriptor> tagtmps=tb.tqi.tq.tags;
331 for(int i=0;i<tagtmps.size();i++) {
332 TempDescriptor tmp=tagtmps.get(i);
333 table.put(tmp, tb.getTag(tmp));
335 for(int i=0;i<fm.numParameters();i++) {
336 TempDescriptor tmp=fm.getParameter(i);
337 table.put(tmp, tb.getParameter(i));
344 new flag states created
345 new tag states created
346 flag states bound to tag parameters
349 public boolean canEnqueue(TaskDescriptor td, int paramnum, FlagState fs) {
350 return typeutil.isSuperorType(td.getParamType(paramnum).getClassDesc(),fs.getClassDescriptor())&&
351 isTaskTrigger_flag(td.getFlag(td.getParameter(paramnum)),fs)&&
352 isTaskTrigger_tag(td.getTag(td.getParameter(paramnum)),fs);
355 private static boolean isTaskTrigger_flag(FlagExpressionNode fen, FlagState fs) {
358 else if (fen instanceof FlagNode)
359 return fs.get(((FlagNode)fen).getFlag());
361 switch (((FlagOpNode)fen).getOp().getOp()) {
362 case Operation.LOGIC_AND:
363 return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) && (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs)));
364 case Operation.LOGIC_OR:
365 return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) || (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs)));
366 case Operation.LOGIC_NOT:
367 return !(isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs));
374 private static boolean isTaskTrigger_tag(TagExpressionList tel, FlagState fs){
376 for (int i=0;i<tel.numTags() ; i++){
377 switch (fs.getTagCount(tel.getType(i))){
378 case FlagState.ONETAG:
379 case FlagState.MULTITAGS:
381 case FlagState.NOTAGS:
389 TagState createInitialState() {
390 ClassDescriptor startupobject=typeutil.getClass(TypeUtil.StartupClass);
391 FlagDescriptor fd=(FlagDescriptor)startupobject.getFlagTable().get(FlagDescriptor.InitialFlag);
392 FlagState fsstartup=(new FlagState(startupobject)).setFlag(fd,true);
393 fsstartup.setAsSourceNode();
394 fsstartup=canonical(fsstartup);
395 TagState ts=new TagState();
396 TagState[] tsarray=ts.addFS(fsstartup);
397 return canonical(tsarray[0]);
400 FlagState canonical(FlagState fs) {
404 TagState canonical(TagState ts) {