1 package Analysis.TaskStateAnalysis;
2 import Analysis.TaskStateAnalysis.*;
8 import java.io.FileWriter;
9 import java.io.FileOutputStream;
12 public class TaskAnalysis {
16 Hashtable extern_flags;
17 Queue<FlagState> toprocess;
25 * @param state a flattened State object
27 * @param map Hashtable containing the temp to var mapping
29 public TaskAnalysis(State state,Hashtable map)
33 this.typeutil=new TypeUtil(state);
36 /** This function builds a table of flags for each class **/
38 private void getFlagsfromClasses() {
39 flags=new Hashtable();
40 extern_flags = new Hashtable();
42 for(Iterator it_classes=state.getClassSymbolTable().getDescriptorsIterator();it_classes.hasNext();) {
44 ClassDescriptor cd = (ClassDescriptor)it_classes.next();
45 System.out.println(cd.getSymbol());
46 Vector vFlags=new Vector();
47 FlagDescriptor flag[];
51 /* Adding the flags of the super class */
52 if (cd.getSuper()!=null) {
53 ClassDescriptor superdesc=cd.getSuperDesc();
55 for(Iterator it_cflags=superdesc.getFlags();it_cflags.hasNext();) {
56 FlagDescriptor fd = (FlagDescriptor)it_cflags.next();
57 System.out.println(fd.toString());
62 for(Iterator it_cflags=cd.getFlags();it_cflags.hasNext();) {
63 FlagDescriptor fd = (FlagDescriptor)it_cflags.next();
64 System.out.println(fd.toString());
68 if (vFlags.size()!=0) {
69 flag=new FlagDescriptor[vFlags.size()];
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]);
78 for(int i=0;i < vFlags.size() ; i++) {
79 flag[i+ctr]=(FlagDescriptor)vFlags.get(i);
81 extern_flags.put(cd,new Integer(ctr));
88 public void taskAnalysis() throws java.io.IOException {
89 flagstates=new Hashtable();
90 Hashtable<FlagState,FlagState> sourcenodes;
92 getFlagsfromClasses();
95 toprocess=new LinkedList<FlagState>();
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);
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);
108 flagstates.put(cd,new Hashtable<FlagState,FlagState>());
112 ClassDescriptor startupobject=typeutil.getClass(TypeUtil.StartupClass);
114 sourcenodes=(Hashtable<FlagState,FlagState>)flagstates.get(startupobject);
116 FlagState fsstartup=new FlagState(startupobject);
117 FlagDescriptor[] fd=(FlagDescriptor[])flags.get(startupobject);
119 fsstartup=fsstartup.setFlag(fd[0],true);
121 sourcenodes.put(fsstartup,fsstartup);
122 toprocess.add(fsstartup);
124 while (!toprocess.isEmpty()) {
125 FlagState trigger=toprocess.poll();
126 createPossibleRuntimeStates(trigger);
127 analyseTasks(trigger);
131 Enumeration e=flagstates.keys();
133 while (e.hasMoreElements()) {
134 System.out.println("creating dot file");
135 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
136 System.out.println((cdtemp.getSymbol()));
137 createDOTfile(cdtemp);
142 private void analyseTasks(FlagState fs) {
143 Hashtable<FlagState,FlagState> sourcenodes;
145 ClassDescriptor cd=fs.getClassDescriptor();
147 sourcenodes=(Hashtable<FlagState,FlagState>)flagstates.get(cd);
149 for(Iterator it_tasks=state.getTaskSymbolTable().getDescriptorsIterator();it_tasks.hasNext();) {
150 TaskDescriptor td = (TaskDescriptor)it_tasks.next();
151 String taskname=td.getSymbol();
154 for(int i=0; i < td.numParameters(); i++) {
155 FlagExpressionNode fen=td.getFlag(td.getParameter(i));
156 if (typeutil.isSuperorType(td.getParamType(i).getClassDesc(),cd)
157 && isTaskTrigger(fen,fs)) {
158 temp=(TempDescriptor)map.get(td.getParameter(i));
167 throw new Error("Illegal Operation: A single flagstate cannot satisfy more than one parameter of a task.");
169 //Iterating through the nodes
170 FlatMethod fm = state.getMethodFlat(td);
171 FlatNode fn=fm.methodEntryNode();
173 HashSet tovisit= new HashSet();
174 HashSet visited= new HashSet();
177 while(!tovisit.isEmpty()) {
178 FlatNode fn1 = (FlatNode)tovisit.iterator().next();
181 // Queue all of the next nodes
182 for(int i = 0; i < fn1.numNext(); i++) {
183 FlatNode nn=fn1.getNext(i);
184 if (!visited.contains(nn))
188 if (fn.kind()==FKind.FlatFlagActionNode) {
189 if (((FlatFlagActionNode)fn).getTaskType() == FlatFlagActionNode.PRE) {
190 throw new Error("PRE FlagActions not supported");
192 } else if (((FlatFlagActionNode)fn).getTaskType() == FlatFlagActionNode.NEWOBJECT) {
193 FlagState fsnew=evalNewObjNode(fn);
194 //Have we seen this node yet
195 if (!sourcenodes.containsKey(fsnew)) {
196 sourcenodes.put(fsnew, fsnew);
197 toprocess.add(fsnew);
199 } else if (((FlatFlagActionNode)fn).getTaskType() == FlatFlagActionNode.TASKEXIT) {
200 FlagState fs_taskexit=evalTaskExitNode(fn,cd,fs);
202 if (!sourcenodes.containsKey(fs_taskexit)) {
203 toprocess.add(fs_taskexit);
205 //seen this node already
206 fs_taskexit=canonicalizeFlagState(sourcenodes,fs_taskexit);
207 Edge newedge=new Edge(fs_taskexit,taskname);
215 private boolean isTaskTrigger(FlagExpressionNode fen,FlagState fs) {
216 if (fen instanceof FlagNode)
217 return fs.get(((FlagNode)fen).getFlag());
219 switch (((FlagOpNode)fen).getOp().getOp()) {
220 case Operation.LOGIC_AND:
221 return ((isTaskTrigger(((FlagOpNode)fen).getLeft(),fs)) && (isTaskTrigger(((FlagOpNode)fen).getRight(),fs)));
222 case Operation.LOGIC_OR:
223 return ((isTaskTrigger(((FlagOpNode)fen).getLeft(),fs)) || (isTaskTrigger(((FlagOpNode)fen).getRight(),fs)));
224 case Operation.LOGIC_NOT:
225 return !(isTaskTrigger(((FlagOpNode)fen).getLeft(),fs));
231 private FlagState evalNewObjNode(FlatNode nn){
232 TempDescriptor[] tdArray = ((FlatFlagActionNode)nn).readsTemps();
234 //Under the safe assumption that all the temps in FFAN.NewObject node are of the same type(class)
235 ClassDescriptor cd_new=tdArray[0].getType().getClassDesc();
237 FlagState fstemp=new FlagState(cd_new);
239 for(Iterator it_tfp=((FlatFlagActionNode)nn).getTempFlagPairs();it_tfp.hasNext();) {
240 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
241 if (! (tfp.getFlag()==null))// condition checks if the new object was created without any flag setting
243 fstemp=fstemp.setFlag(tfp.getFlag(),((FlatFlagActionNode)nn).getFlagChange(tfp));
251 private FlagState evalTaskExitNode(FlatNode nn,ClassDescriptor cd,FlagState fs){
254 for(Iterator it_tfp=((FlatFlagActionNode)nn).getTempFlagPairs();it_tfp.hasNext();) {
255 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
256 if (temp.toString().equals(tfp.getTemp().toString()))
257 fstemp=fstemp.setFlag(tfp.getFlag(),((FlatFlagActionNode)nn).getFlagChange(tfp));
263 private FlagState canonicalizeFlagState(Hashtable sourcenodes, FlagState fs){
264 if (sourcenodes.containsKey(fs))
265 return (FlagState)sourcenodes.get(fs);
267 sourcenodes.put(fs,fs);
272 public void createDOTfile(ClassDescriptor cd) throws java.io.IOException {
273 File dotfile= new File("graph"+cd.getSymbol()+".dot");
274 FileOutputStream dotstream=new FileOutputStream(dotfile,true);
275 FlagState.DOTVisitor.visit(dotstream,((Hashtable)flagstates.get(cd)).values());
279 private String getTaskName(TaskDescriptor td) {
280 StringTokenizer st = new StringTokenizer(td.toString(),"(");
281 return st.nextToken();
284 private void createPossibleRuntimeStates(FlagState fs) {
285 ClassDescriptor cd = fs.getClassDescriptor();
286 Hashtable<FlagState,FlagState> sourcenodes=(Hashtable<FlagState,FlagState>)flagstates.get(cd);
287 FlagDescriptor[] fd=(FlagDescriptor[])flags.get(cd);
288 int externs=((Integer)extern_flags.get(cd)).intValue();
292 int noOfIterations=(1<<externs) - 1;
293 boolean BoolValTable[]=new boolean[externs];
296 for(int i=0; i < externs ; i++) {
297 BoolValTable[i]=fs.get(fd[i]);
301 for(int k=0; k<noOfIterations; k++) {
302 for(int j=0; j < externs ;j++) {
303 if ((k% (1<<j)) == 0)
304 BoolValTable[j]=(!BoolValTable[j]);
309 for(int i=0; i < externs;i++) {
310 fstemp=fstemp.setFlag(fd[i],BoolValTable[i]);
312 if (!sourcenodes.containsKey(fstemp))
313 toprocess.add(fstemp);
315 fstemp=canonicalizeFlagState(sourcenodes,fstemp);
316 fs.addEdge(new Edge(fstemp,"Runtime"));