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