1 package Analysis.TaskStateAnalysis;
2 import Analysis.TaskStateAnalysis.*;
8 import java.io.FileWriter;
9 import java.io.FileOutputStream;
11 public class TaskAnalysis {
15 Hashtable extern_flags;
16 Queue<FlagState> toprocess;
17 TagAnalysis taganalysis;
24 * @param state a flattened State object
27 public TaskAnalysis(State state, TagAnalysis taganalysis)
30 this.typeutil=new TypeUtil(state);
31 this.taganalysis=taganalysis;
34 /** Builds a table of flags for each class in the Bristlecone program.
35 * It creates two hashtables: one which holds the ClassDescriptors and arrays of
36 * FlagDescriptors as key-value pairs; the other holds the ClassDescriptor and the
37 * number of external flags for that specific class.
40 private void getFlagsfromClasses() {
41 flags=new Hashtable();
42 extern_flags = new Hashtable();
44 /** Iterate through the classes used in the program to build the table of flags
46 for(Iterator it_classes=state.getClassSymbolTable().getDescriptorsIterator();it_classes.hasNext();) {
48 ClassDescriptor cd = (ClassDescriptor)it_classes.next();
49 System.out.println(cd.getSymbol());
50 Vector vFlags=new Vector();
51 FlagDescriptor flag[];
55 /* Adding the flags of the super class */
56 if (cd.getSuper()!=null) {
57 ClassDescriptor superdesc=cd.getSuperDesc();
59 for(Iterator it_cflags=superdesc.getFlags();it_cflags.hasNext();) {
60 FlagDescriptor fd = (FlagDescriptor)it_cflags.next();
61 System.out.println(fd.toString());
66 for(Iterator it_cflags=cd.getFlags();it_cflags.hasNext();) {
67 FlagDescriptor fd = (FlagDescriptor)it_cflags.next();
71 if (vFlags.size()!=0) {
72 flag=new FlagDescriptor[vFlags.size()];
74 for(int i=0;i < vFlags.size() ; i++) {
75 if (((FlagDescriptor)vFlags.get(i)).getExternal()) {
76 flag[ctr]=(FlagDescriptor)vFlags.get(i);
77 vFlags.remove(flag[ctr]);
81 for(int i=0;i < vFlags.size() ; i++) {
82 flag[i+ctr]=(FlagDescriptor)vFlags.get(i);
84 extern_flags.put(cd,new Integer(ctr));
90 /** Method which starts up the analysis
94 public void taskAnalysis() throws java.io.IOException {
95 flagstates=new Hashtable();
96 Hashtable<FlagState,FlagState> sourcenodes;
99 getFlagsfromClasses();
102 toprocess=new LinkedList<FlagState>();
104 for(Iterator it_classes=(Iterator)flags.keys();it_classes.hasNext();) {
105 ClassDescriptor cd=(ClassDescriptor)it_classes.next();
106 externs=((Integer)extern_flags.get(cd)).intValue();
107 FlagDescriptor[] fd=(FlagDescriptor[])flags.get(cd);
110 System.out.println("Inside taskAnalysis;\n Class:"+ cd.getSymbol());
111 System.out.println("No of externs " + externs);
112 System.out.println("No of flags: "+fd.length);
115 flagstates.put(cd,new Hashtable<FlagState,FlagState>());
119 ClassDescriptor startupobject=typeutil.getClass(TypeUtil.StartupClass);
121 sourcenodes=(Hashtable<FlagState,FlagState>)flagstates.get(startupobject);
123 FlagState fsstartup=new FlagState(startupobject);
124 FlagDescriptor[] fd=(FlagDescriptor[])flags.get(startupobject);
126 fsstartup=fsstartup.setFlag(fd[0],true);
128 sourcenodes.put(fsstartup,fsstartup);
129 toprocess.add(fsstartup);
131 /** Looping through the flagstates in the toprocess queue to perform the state analysis */
132 while (!toprocess.isEmpty()) {
133 FlagState trigger=toprocess.poll();
134 createPossibleRuntimeStates(trigger);
136 analyseTasks(trigger);
139 /** Creating DOT files */
140 Enumeration e=flagstates.keys();
142 while (e.hasMoreElements()) {
143 System.out.println("creating dot file");
144 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
145 System.out.println((cdtemp.getSymbol()));
146 createDOTfile(cdtemp);
151 /** Analyses the set of tasks based on the given flagstate, checking
152 * to see which tasks are triggered and what new flagstates are created
153 * from the base flagstate.
154 * @param fs A FlagState object which is used to analyse the task
158 private void analyseTasks(FlagState fs) {
159 ClassDescriptor cd=fs.getClassDescriptor();
160 Hashtable<FlagState,FlagState> sourcenodes=(Hashtable<FlagState,FlagState>)flagstates.get(cd);
162 for(Iterator it_tasks=state.getTaskSymbolTable().getDescriptorsIterator();it_tasks.hasNext();) {
163 TaskDescriptor td = (TaskDescriptor)it_tasks.next();
164 String taskname=td.getSymbol();
167 System.out.println();
168 System.out.println(cd.getSymbol()+" : "+fs.getTextLabel());
169 System.out.println("Task: "+taskname);
172 /** counter to keep track of the number of parameters (of the task being analyzed) that
173 * are satisfied by the flagstate.
176 TempDescriptor temp=null;
177 FlatMethod fm = state.getMethodFlat(td);
179 for(int i=0; i < td.numParameters(); i++) {
180 FlagExpressionNode fen=td.getFlag(td.getParameter(i));
181 TagExpressionList tel=td.getTag(td.getParameter(i));
183 /** Checking to see if the parameter is of the same type/class as the
184 * flagstate's and also if the flagstate fs triggers the given task*/
185 if (typeutil.isSuperorType(td.getParamType(i).getClassDesc(),cd)
186 && isTaskTrigger_flag(fen,fs)
187 && isTaskTrigger_tag(tel,fs)) {
188 temp=fm.getParameter(i);
193 if (trigger_ctr==0) //Look at next task
197 throw new Error("Illegal Operation: A single flagstate cannot satisfy more than one parameter of a task.");
201 System.out.println("Task:" + taskname +" is triggered");
204 Set newstates=taganalysis.getFlagStates(td);
205 for(Iterator fsit=newstates.iterator();fsit.hasNext();) {
206 FlagState fsnew=(FlagState) fsit.next();
207 if (! ((Hashtable<FlagState,FlagState>)flagstates.get(fsnew.getClassDescriptor())).containsKey(fsnew)) {
208 ((Hashtable<FlagState,FlagState>)flagstates.get(fsnew.getClassDescriptor())).put(fsnew, fsnew);
209 toprocess.add(fsnew);
213 //Iterating through the nodes
214 Set nodeset=fm.getNodeSet();
216 for(Iterator nodeit=nodeset.iterator();nodeit.hasNext();) {
217 FlatNode fn1 = (FlatNode) nodeit.next();
219 if (fn1.kind()==FKind.FlatFlagActionNode) {
220 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
221 if (ffan.getTaskType() == FlatFlagActionNode.PRE) {
222 if (ffan.getTempFlagPairs().hasNext()||ffan.getTempTagPairs().hasNext())
223 throw new Error("PRE FlagActions not supported");
225 } else if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
227 System.out.println("TASKEXIT");
230 Vector<FlagState> fsv_taskexit=evalTaskExitNode(ffan,cd,fs,temp);
232 for(Enumeration en=fsv_taskexit.elements();en.hasMoreElements();){
233 FlagState fs_taskexit=(FlagState)en.nextElement();
234 if (!sourcenodes.containsKey(fs_taskexit)) {
235 toprocess.add(fs_taskexit);
238 //seen this node already
239 fs_taskexit=canonicalizeFlagState(sourcenodes,fs_taskexit);
240 FEdge newedge=new FEdge(fs_taskexit,taskname);
241 //FEdge newedge=new FEdge(fs_taskexit,td);
251 /** Determines whether the given flagstate satisfies a
252 * single parameter in the given task.
253 * @param fen FlagExpressionNode
254 * @see FlagExpressionNode
255 * @param fs FlagState
257 * @return <CODE>true</CODE> if fs satisfies the boolean expression
258 denoted by fen else <CODE>false</CODE>.
262 private boolean isTaskTrigger_flag(FlagExpressionNode fen,FlagState fs) {
263 if (fen instanceof FlagNode)
264 return fs.get(((FlagNode)fen).getFlag());
266 switch (((FlagOpNode)fen).getOp().getOp()) {
267 case Operation.LOGIC_AND:
268 return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) && (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs)));
269 case Operation.LOGIC_OR:
270 return ((isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs)) || (isTaskTrigger_flag(((FlagOpNode)fen).getRight(),fs)));
271 case Operation.LOGIC_NOT:
272 return !(isTaskTrigger_flag(((FlagOpNode)fen).getLeft(),fs));
278 private boolean isTaskTrigger_tag(TagExpressionList tel, FlagState fs){
281 for (int i=0;i<tel.numTags() ; i++){
282 switch (fs.getTagCount(tel.getType(i))){
283 case FlagState.ONETAG:
284 case FlagState.MULTITAGS:
286 case FlagState.NOTAGS:
294 /*private int tagTypeCount(TagExpressionList tel, String tagtype){
296 for(int i=0;i<tel.numTags() ; i++){
297 if (tel.getType(i).equals(tagtype))
303 /** Evaluates a NewObject Node and returns the newly created
304 * flagstate to add to the process queue.
311 private FlagState evalNewObjNode(FlatNode nn){
313 ClassDescriptor cd_new=((FlatNew)nn.getPrev(0)).getType().getClassDesc();
316 //TempDescriptor[] tdArray = ((FlatFlagActionNode)nn).readsTemps();
318 //if (tdArray.length==0)
321 //Under the safe assumption that all the temps in FFAN.NewObject node are of the same type(class)
322 //ClassDescriptor cd_new=tdArray[0].getType().getClassDesc();
324 FlagState fstemp=new FlagState(cd_new);
326 for(Iterator it_tfp=((FlatFlagActionNode)nn).getTempFlagPairs();it_tfp.hasNext();) {
327 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
328 if (! (tfp.getFlag()==null))// condition checks if the new object was created without any flag setting
330 fstemp=fstemp.setFlag(tfp.getFlag(),((FlatFlagActionNode)nn).getFlagChange(tfp));
336 for(Iterator it_ttp=((FlatFlagActionNode)nn).getTempTagPairs();it_ttp.hasNext();) {
337 TempTagPair ttp=(TempTagPair)it_ttp.next();
338 if (! (ttp.getTag()==null)){
339 fstemp=fstemp.setTag(ttp.getTag());
348 private Vector<FlagState> evalTaskExitNode(FlatNode nn,ClassDescriptor cd,FlagState fs, TempDescriptor temp){
350 //FlagState[] fstemparray=new FlagState[3];
351 Vector<FlagState> inprocess=new Vector<FlagState>();
352 Vector<FlagState> processed=new Vector<FlagState>();
354 for(Iterator it_tfp=((FlatFlagActionNode)nn).getTempFlagPairs();it_tfp.hasNext();) {
355 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
356 if (temp==tfp.getTemp())
357 fstemp=fstemp.setFlag(tfp.getFlag(),((FlatFlagActionNode)nn).getFlagChange(tfp));
360 inprocess.add(fstemp);
361 processed.add(fstemp);
363 for(Iterator it_ttp=((FlatFlagActionNode)nn).getTempTagPairs();it_ttp.hasNext();) {
364 TempTagPair ttp=(TempTagPair)it_ttp.next();
366 if (temp==ttp.getTemp()){
367 processed=new Vector<FlagState>();
368 for (Enumeration en=inprocess.elements();en.hasMoreElements();){
369 FlagState fsworking=(FlagState)en.nextElement();
370 if (((FlatFlagActionNode)nn).getTagChange(ttp)){
371 fsworking=fsworking.setTag(ttp.getTag());
372 processed.add(fsworking);
376 processed.addAll(Arrays.asList(fsworking.clearTag(ttp.getTag())));
387 private FlagState canonicalizeFlagState(Hashtable sourcenodes, FlagState fs){
388 if (sourcenodes.containsKey(fs))
389 return (FlagState)sourcenodes.get(fs);
391 sourcenodes.put(fs,fs);
396 /** Creates a DOT file using the flagstates for a given class
397 * @param cd ClassDescriptor of the class
398 * @throws java.io.IOException
399 * @see ClassDescriptor
402 public void createDOTfile(ClassDescriptor cd) throws java.io.IOException {
403 File dotfile_flagstates= new File("graph"+cd.getSymbol()+".dot");
404 FileOutputStream dotstream=new FileOutputStream(dotfile_flagstates,true);
405 FlagState.DOTVisitor.visit(dotstream,((Hashtable)flagstates.get(cd)).values());
407 File dotfile_tasknodes=new File("graph"+cd.getSymbol()+"_task.dot");
408 dotstream=new FileOutputStream(dotfile_tasknodes,true);
409 TaskNode.DOTVisitor.visit(dotstream,(produceTaskNodes((Hashtable)flagstates.get(cd))).values());
413 private void createPossibleRuntimeStates(FlagState fs) {
414 ClassDescriptor cd = fs.getClassDescriptor();
415 Hashtable<FlagState,FlagState> sourcenodes=(Hashtable<FlagState,FlagState>)flagstates.get(cd);
416 FlagDescriptor[] fd=(FlagDescriptor[])flags.get(cd);
417 int externs=((Integer)extern_flags.get(cd)).intValue();
422 int noOfIterations=(1<<externs) - 1;
423 boolean BoolValTable[]=new boolean[externs];
426 for(int i=0; i < externs ; i++) {
427 BoolValTable[i]=fs.get(fd[i]);
430 for(int k=0; k<noOfIterations; k++) {
431 for(int j=0; j < externs ;j++) {
432 if ((k% (1<<j)) == 0)
433 BoolValTable[j]=(!BoolValTable[j]);
438 for(int i=0; i < externs;i++) {
439 fstemp=fstemp.setFlag(fd[i],BoolValTable[i]);
441 if (!sourcenodes.containsKey(fstemp))
442 toprocess.add(fstemp);
444 fstemp=canonicalizeFlagState(sourcenodes,fstemp);
445 fs.addEdge(new FEdge(fstemp,"Runtime"));
449 private TaskNode canonicalizeTaskNode(Hashtable nodes, TaskNode node){
450 if (nodes.containsKey(node))
451 return (TaskNode)nodes.get(node);
453 nodes.put(node,node);
454 return (TaskNode)node;
458 public Hashtable produceTaskNodes(Hashtable<FlagState,FlagState> fsnodes){
460 Hashtable<TaskNode,TaskNode> tasknodes=new Hashtable<TaskNode,TaskNode>();
461 for(Enumeration en=fsnodes.keys();en.hasMoreElements();){
462 FlagState fs=(FlagState)en.nextElement();
464 Iterator it_inedges=fs.inedges();
467 if (!fs.inedges().hasNext()){
468 tn=new TaskNode("Start Node");
470 FEdge inedge=(FEdge)it_inedges.next();
471 tn=new TaskNode(inedge.getLabel());
473 if(fs.edges().hasNext()){
474 tn=(TaskNode)canonicalizeTaskNode(tasknodes, tn);
475 for (Iterator it_edges=fs.edges();it_edges.hasNext();){
476 TaskNode target=new TaskNode(((FEdge)it_edges.next()).getLabel());
477 target=(TaskNode)canonicalizeTaskNode(tasknodes,target);
478 tn.addEdge(new TEdge(target));
481 }while(it_inedges.hasNext());