changes to give flagstates a machine readable name
[IRC.git] / Robust / src / Analysis / TaskStateAnalysis / TaskAnalysis.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.File;
8 import java.io.FileWriter;
9 import java.io.FileOutputStream;
10
11
12 public class TaskAnalysis {
13     State state;
14     Hashtable flagstates;
15     Hashtable flags;
16     Hashtable extern_flags;
17     Queue<FlagState> q_main;
18     Hashtable map;
19     TempDescriptor temp;
20     TypeUtil typeutil;
21     
22     /** 
23      * Class Constructor
24      *
25      * @param state a flattened State object
26      * @see State
27      * @param map Hashtable containing the temp to var mapping
28      */
29     public TaskAnalysis(State state,Hashtable map)
30     {
31         this.state=state;
32         this.map=map;
33         this.typeutil=new TypeUtil(state);
34     }
35     
36     /** This function builds a table of flags for each class **/
37
38     private void getFlagsfromClasses() {
39         flags=new Hashtable();
40         extern_flags = new Hashtable();
41         
42         for(Iterator it_classes=state.getClassSymbolTable().getDescriptorsIterator();it_classes.hasNext();) {
43                 
44             ClassDescriptor cd = (ClassDescriptor)it_classes.next();
45             System.out.println(cd.getSymbol());
46             Vector vFlags=new Vector();
47             FlagDescriptor flag[];
48             int ctr=0;
49             
50             
51             /* Adding the flags of the super class */
52             if (cd.getSuper()!=null) {
53                 ClassDescriptor superdesc=cd.getSuperDesc();
54                 
55                 for(Iterator it_cflags=superdesc.getFlags();it_cflags.hasNext();) {     
56                     FlagDescriptor fd = (FlagDescriptor)it_cflags.next();
57                     System.out.println(fd.toString());
58                     vFlags.add(fd);
59                 }
60             }
61
62             for(Iterator it_cflags=cd.getFlags();it_cflags.hasNext();) {
63                 FlagDescriptor fd = (FlagDescriptor)it_cflags.next();
64                 System.out.println(fd.toString());
65                 vFlags.add(fd);
66             }
67
68             if (vFlags.size()!=0) {
69                 flag=new FlagDescriptor[vFlags.size()];
70                 
71                 for(int i=0;i < vFlags.size() ; i++) {
72                     if (((FlagDescriptor)vFlags.get(i)).getExternal()) {
73                         flag[ctr]=(FlagDescriptor)vFlags.get(i);
74                         vFlags.remove(flag[ctr]);
75                         ctr++;
76                     }
77                 }
78                 for(int i=0;i < vFlags.size() ; i++) {
79                     flag[i+ctr]=(FlagDescriptor)vFlags.get(i);
80                 }
81                 extern_flags.put(cd,new Integer(ctr));
82                 flags.put(cd,flag);
83                 
84             }
85         }
86     }
87
88     public void taskAnalysis() throws java.io.IOException {
89         flagstates=new Hashtable();
90         Hashtable<FlagState,FlagState> sourcenodes;
91         
92         getFlagsfromClasses();
93         
94         int externs;
95         q_main=new LinkedList<FlagState>();
96         
97         for(Iterator it_classes=(Iterator)flags.keys();it_classes.hasNext();) {
98             ClassDescriptor cd=(ClassDescriptor)it_classes.next();
99             externs=((Integer)extern_flags.get(cd)).intValue();
100             FlagDescriptor[] fd=(FlagDescriptor[])flags.get(cd);
101
102             //Debug block
103             System.out.println("Inside taskAnalysis;\n Class:"+ cd.getSymbol());
104             System.out.println("No of externs " + externs);
105             System.out.println("No of flags: "+fd.length);
106             //Debug block
107             
108            flagstates.put(cd,new Hashtable<FlagState,FlagState>());
109         }       
110         
111         
112         ClassDescriptor startupobject=typeutil.getClass(TypeUtil.StartupClass);
113         
114         sourcenodes=(Hashtable<FlagState,FlagState>)flagstates.get(startupobject);
115         
116         FlagState fsstartup=new FlagState(startupobject);
117         FlagDescriptor[] fd=(FlagDescriptor[])flags.get(startupobject);
118                     
119         fsstartup=fsstartup.setFlag(fd[0],true);
120         
121         sourcenodes.put(fsstartup,fsstartup);
122                             
123         Queue<FlagState> q_temp=analyseTasks(fsstartup);
124
125         if ( q_temp != null) {
126                 q_main.addAll(q_temp);
127         }
128         
129         while (q_main.size() > 0) {
130             // ****debug block********
131             
132             System.out.println("/***********contents of main q before pop**********/");
133             for (Iterator it_qm=q_main.iterator();it_qm.hasNext();)
134                 {
135                     
136                     FlagState fs_qm=(FlagState)it_qm.next();
137                     
138                     System.out.println("FS : "+fs_qm.getClassDescriptor().toString()+" : "+fs_qm.toString((FlagDescriptor [])flags.get(fs_qm.getClassDescriptor())));
139                 } 
140             System.out.println("/*********************************/");
141             // ****debug block********
142             FlagState trigger=q_main.poll();
143             
144            
145             q_temp=createPossibleRuntimeStates(trigger);
146             
147             if ( q_temp != null){
148                     q_main.addAll(q_temp);
149                     
150                 // ****debug block********
151             
152             System.out.println("/***********contents of main q**********/");
153             for (Iterator it_qm=q_main.iterator();it_qm.hasNext();)
154                 {
155                     
156                     FlagState fs_qm=(FlagState)it_qm.next();
157                     
158                     System.out.println("FS : "+fs_qm.getClassDescriptor().toString()+" : "+fs_qm.toString((FlagDescriptor [])flags.get(fs_qm.getClassDescriptor())));
159                 } 
160             System.out.println("/*********************************/");
161             // ****debug block********
162             
163             q_temp=analyseTasks(trigger);
164             
165             if ( q_temp != null) 
166                         q_main.addAll(q_temp);
167                         
168                 // ****debug block********
169             
170             System.out.println("/***********contents of main q after analyse tasks**********/");
171             for (Iterator it_qm=q_main.iterator();it_qm.hasNext();)
172                 {
173                     
174                     FlagState fs_qm=(FlagState)it_qm.next();
175                     
176                     System.out.println("FS : "+fs_qm.getClassDescriptor().toString()+" : "+fs_qm.toString((FlagDescriptor [])flags.get(fs_qm.getClassDescriptor())));
177                 } 
178             System.out.println("/*********************************/");
179             // ****debug block********
180             
181         }
182         }
183         
184         //Creating DOT files
185         Enumeration e=flagstates.keys();
186
187         while (e.hasMoreElements()) {
188             System.out.println("creating dot file");
189             ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
190             System.out.println((cdtemp.getSymbol()));
191             createDOTfile(cdtemp);
192         }
193         
194     
195         }
196
197
198     public Queue<FlagState> analyseTasks(FlagState fs) throws java.io.IOException {
199         
200         
201         Hashtable<FlagState,FlagState> sourcenodes;
202         Queue<FlagState> q_retval;
203         
204         
205         
206         ClassDescriptor cd=fs.getClassDescriptor();
207         
208         sourcenodes=(Hashtable<FlagState,FlagState>)flagstates.get(cd);
209         
210         int externs=((Integer)extern_flags.get(cd)).intValue();
211         FlagDescriptor[] fd=(FlagDescriptor[])flags.get(cd);
212
213         q_retval=new LinkedList<FlagState>();
214         //***Debug Block***
215
216         //while (q.size() != 0) {
217             System.out.println("inside while loop in analysetasks \n");
218             
219             //***Debug Block***
220             //FlagDescriptor[] ftemp=(FlagDescriptor[])flags.get(cd);
221             //System.out.println("Processing state: "+cd.getSymbol()+" " + fsworking.toString(ftemp));
222             //***Debug Block***
223
224                     
225             for(Iterator it_tasks=state.getTaskSymbolTable().getDescriptorsIterator();it_tasks.hasNext();) {
226                 TaskDescriptor td = (TaskDescriptor)it_tasks.next();
227                 boolean taskistriggered=false;
228                 int trigger_ctr=0;
229                 String taskname=getTaskName(td);
230                 
231                 
232
233                 //***Debug Block***
234                 
235                 System.out.println("Method: AnalyseTasks");
236                 System.out.println(taskname);
237                 System.out.println();
238                 
239                 //***Debug Block***
240                 
241                 
242                 
243                 for(int i=0; i < td.numParameters(); i++) {
244                     FlagExpressionNode fen=td.getFlag(td.getParameter(i));
245                     //if ( (td.getParamType(i).equals(cd))&&(isTaskTrigger(fen,fs))){
246                         if ((isParamOfSameClass(td.getParamType(i),cd)) && (isTaskTrigger(fen,fs))){
247                                 taskistriggered = true;
248                                 System.out.println(td.getParamType(i).toString()+"   "+cd.toString());
249                                 temp=(TempDescriptor)map.get(td.getParameter(i));
250                                 trigger_ctr++;
251                         }
252                 }
253                 
254                 if (trigger_ctr>1)
255                         throw new Error("Illegal Operation: A single flagstate cannot satisfy more than one parameter of a task.");
256
257                 if (taskistriggered) {
258                     //***Debug Block***
259                     //
260                     System.out.println("inside taskistriggered");
261                     
262                     //***Debug Block***
263                     
264                     taskistriggered=false;
265                     if (!wasFlagStateProcessed(sourcenodes,fs)){
266                                 sourcenodes.put(fs,fs);
267                         }
268                         else{
269                                 fs=sourcenodes.get(fs);
270                         }
271                                         
272                         //Iterating through the nodes
273                     FlatMethod fm = state.getMethodFlat(td);
274                     FlatNode fn=fm.methodEntryNode();
275                     
276                     HashSet tovisit= new HashSet();
277                     HashSet visited= new HashSet();
278                     
279                     tovisit.add(fn);
280                     while(!tovisit.isEmpty()) {
281                         FlatNode fn1 = (FlatNode)tovisit.iterator().next();
282                         tovisit.remove(fn1);
283                         visited.add(fn1);
284                         for(int i = 0; i < fn1.numNext(); i++) {
285                             FlatNode nn=fn1.getNext(i);
286                             if (nn.kind()==FKind.FlatFlagActionNode) {
287                                 //***Debug Block***
288                                 if (((FlatFlagActionNode)nn).getTaskType() == FlatFlagActionNode.PRE) {
289                                     throw new Error("PRE FlagActions not supported");
290                                     
291                                 } else if (((FlatFlagActionNode)nn).getTaskType() == FlatFlagActionNode.NEWOBJECT) {
292                                     //***Debug Block***
293                                     System.out.println("NEWObject");
294                                     //***Debug Block***
295                                     
296                                     q_retval.offer(evalNewObjNode(nn));
297                                 }
298                                 if (((FlatFlagActionNode)nn).getTaskType() == FlatFlagActionNode.TASKEXIT) {
299                                     //***Debug Block***
300                                         System.out.println("TaskExit");
301                                     //***Debug Block***
302                                     FlagState fs_taskexit=evalTaskExitNode(nn,cd,fs);
303                     
304                                     Edge newedge=new Edge(fs_taskexit,taskname);
305                                     if (!edgeexists(fs,newedge)) {
306                                                 fs.addEdge(newedge);
307                                     }
308                                     if ((!wasFlagStateProcessed(sourcenodes,fs_taskexit)) && (!existsInQMain(fs_taskexit)) && (!existsInQ(q_retval,fs_taskexit))){
309                                         q_retval.offer(fs_taskexit);
310                                     }
311                                 }
312                             }
313                             
314                             if (!visited.contains(nn) && !tovisit.contains(nn)) {
315                                 tovisit.add(nn);
316                             }
317                         }
318                     
319                         }
320             }
321         }
322         if (q_retval.size()==0)
323             return null;
324         else
325             return q_retval;
326     }
327
328     private boolean isTaskTrigger(FlagExpressionNode fen,FlagState fs) {
329         if (fen instanceof FlagNode)
330             return fs.get(((FlagNode)fen).getFlag());
331         else
332             switch (((FlagOpNode)fen).getOp().getOp()) {
333             case Operation.LOGIC_AND:
334                 return ((isTaskTrigger(((FlagOpNode)fen).getLeft(),fs)) && (isTaskTrigger(((FlagOpNode)fen).getRight(),fs)));
335             case Operation.LOGIC_OR:
336                 return ((isTaskTrigger(((FlagOpNode)fen).getLeft(),fs)) || (isTaskTrigger(((FlagOpNode)fen).getRight(),fs)));
337             case Operation.LOGIC_NOT:
338                 return !(isTaskTrigger(((FlagOpNode)fen).getLeft(),fs));
339             default:
340                 return false;
341             }
342     }
343     
344     private boolean isParamOfSameClass(TypeDescriptor typedesc, ClassDescriptor classdesc){
345            /* Set subclasses=typeutil.getSubClasses(classdesc);
346             if (subclasses!=null){
347                         if (subclasses.contains(typedesc.getClassDesc()) || typedesc.getClassDesc().equals(classdesc))
348                                 return true;
349                         else
350                                 return false;
351                 }
352                 else{
353                         if (typedesc.getClassDesc().equals(classdesc))
354                                 return true;
355                         else
356                                 return false;
357                 }*/
358                 
359                  return typeutil.isSuperorType(classdesc,typedesc.getClassDesc());
360                         
361                         
362         }
363     
364     
365     private FlagState evalNewObjNode(FlatNode nn){
366             TempDescriptor[] tdArray = ((FlatFlagActionNode)nn).readsTemps();
367                                     
368                 //Under the safe assumption that all the temps in FFAN.NewObject node are of the same type(class)
369                 ClassDescriptor cd_new=tdArray[0].getType().getClassDesc();
370                                     
371                 FlagState fstemp=new FlagState(cd_new);
372                                     
373                 for(Iterator it_tfp=((FlatFlagActionNode)nn).getTempFlagPairs();it_tfp.hasNext();) {
374                         TempFlagPair tfp=(TempFlagPair)it_tfp.next();
375                         if (! (tfp.getFlag()==null))// condition checks if the new object was created without any flag setting
376                         {                                       
377                                 fstemp=fstemp.setFlag(tfp.getFlag(),((FlatFlagActionNode)nn).getFlagChange(tfp));
378                         }
379                         else
380                                 break;
381                 }       
382                 return fstemp;
383         }
384         
385         private FlagState evalTaskExitNode(FlatNode nn,ClassDescriptor cd,FlagState fs){
386                 FlagState fstemp=fs;
387                                     
388                 for(Iterator it_tfp=((FlatFlagActionNode)nn).getTempFlagPairs();it_tfp.hasNext();) {
389                         TempFlagPair tfp=(TempFlagPair)it_tfp.next();
390                         if (temp.toString().equals(tfp.getTemp().toString()))
391                                 fstemp=fstemp.setFlag(tfp.getFlag(),((FlatFlagActionNode)nn).getFlagChange(tfp));
392                 }
393                 return fstemp;
394         }               
395             
396
397     private boolean wasFlagStateProcessed(Hashtable sourcenodes,FlagState fs) {
398                 if (sourcenodes.containsKey(fs))
399                         return true;
400                 else
401                         return false;
402     }
403
404    /* private boolean existsInQueue(TriggerState ts) {
405         throw new Error("Use hashcode/contains of set method to find...no linear search allowed");
406     }*/
407
408     private boolean existsInQMain(FlagState fs) {
409                 if (q_main.contains(fs))
410                         return true;
411                 else
412                         return false;    
413     }
414     
415     private boolean existsInQ(Queue q,FlagState fs) {
416                 if (q.contains(fs))
417                         return true;
418                 else
419                         return false;    
420     }
421
422
423    /* public void printAdjList(ClassDescriptor cd) {
424         Enumeration e=((Hashtable)Adj_List.get(cd)).keys();
425         while(e.hasMoreElements()) {
426             FlagState fsv = (FlagState)(e.nextElement());
427             System.out.println(fsv.toString((FlagDescriptor [])flags.get(cd)));
428         }
429     }*/
430
431    public void createDOTfile(ClassDescriptor cd) throws java.io.IOException {
432            
433         File dotfile= new File("graph"+cd.getSymbol()+".dot");
434
435         FileOutputStream dotstream=new FileOutputStream(dotfile,true);
436         
437         FlagState.DOTVisitor.visit(dotstream,((Hashtable)flagstates.get(cd)).values());
438    }
439         
440
441     private String getTaskName(TaskDescriptor td) {
442         StringTokenizer st = new StringTokenizer(td.toString(),"(");
443         return st.nextToken();
444     }
445
446    /* private boolean edgeexists(Hashtable Adj_List_local,FlagState v1, FlagState v2,String label) {
447         Vector edges=(Vector)Adj_List_local.get(v1);
448         
449         if (edges != null) {
450             for(int i=0;i < edges.size();i++) {
451                 FlagState fs=((Edge)edges.get(i)).getTarget();
452                 if (fs.equals(v2) && (label.compareTo(((Edge)edges.get(i)).getLabel())==0))
453                     return true;
454             }
455         }
456         return false;
457     }*/
458     
459     private boolean edgeexists(FlagState fs, Edge newedge){
460                 for(Iterator it_edges=fs.edges();it_edges.hasNext();){
461                                 Edge e=(Edge)it_edges.next();
462                                 if (newedge.equals(e))
463                                         return true;
464                 }
465                 return false;
466         }
467
468     private Queue createPossibleRuntimeStates(FlagState fs) throws java.io.IOException {
469         
470                 int noOfIterations, externs;
471                 Hashtable<FlagState,FlagState> sourcenodes;
472         
473         
474                 System.out.println("Inside CreatePossible runtime states");
475         
476                 ClassDescriptor cd = fs.getClassDescriptor();
477         
478                 sourcenodes=(Hashtable<FlagState,FlagState>)flagstates.get(cd);
479                 FlagDescriptor[] fd=(FlagDescriptor[])flags.get(cd);    
480                 externs=((Integer)extern_flags.get(cd)).intValue();
481                 //System.out.println("No of externs:"+externs);
482         
483
484                 Queue<FlagState>  q_ret=new LinkedList<FlagState>();
485
486         
487             noOfIterations=(1<<externs) - 1;
488            // System.out.println("No of iterations: "+noOfIterations);
489             boolean BoolValTable[]=new boolean[externs];
490
491             for(int i=0; i < externs ; i++) {
492                 System.out.println(fd[i].getSymbol());
493                 BoolValTable[i]=fs.get(fd[i]);
494             }
495
496            /* if (! wasFlagStateProcessed(Adj_List_temp,fs)) {
497                         Adj_List_temp.put(fs,new Vector());
498             }
499             */
500             if (externs > 0){
501                 sourcenodes.put(fs,fs);
502             
503                         for(int k=0; k<noOfIterations; k++) {
504                                 for(int j=0; j < externs ;j++) {
505                                     if ((k% (1<<j)) == 0)
506                                                 BoolValTable[j]=(!BoolValTable[j]);
507                                 }
508
509                                 FlagState fstemp=fs;
510                 
511                                 for(int i=0; i < externs;i++) {
512                                     fstemp=fstemp.setFlag(fd[i],BoolValTable[i]);
513                                 }
514                                 fs.addEdge(new Edge(fstemp,"Runtime"));
515                         
516                                 if (!existsInQMain(fstemp) && ! wasFlagStateProcessed(sourcenodes,fstemp)){
517                                         q_ret.add(fstemp);
518                                 }
519                 
520                         }
521                 } 
522                 return q_ret;
523         }
524             
525
526
527
528     private void processTasksWithPost(ClassDescriptor cd, Hashtable pre) {
529     }
530
531     private ClassDescriptor processFlatNew(FlatNode fn) {
532         if (! (fn.getNext(0).kind() == 13)) {
533             return (((FlatNew)fn).getType().getClassDesc());
534         }
535         return null;
536     }
537
538 }