1 package Analysis.TaskStateAnalysis;
8 import java.io.FileWriter;
9 import java.io.FileOutputStream;
12 public class SafetyAnalysis {
14 private Hashtable executiongraph;
15 private Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> safeexecution; //to use to build code
16 private static final int OR = 0;
17 private static final int AND = 1;
18 private Hashtable reducedgraph;
19 private String classname;
21 private TaskAnalysis taskanalysis;
22 private Hashtable<ClassDescriptor, Hashtable> optionaltaskdescriptors;
24 private ClassDescriptor processedclass;
27 public Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> getResult(){
31 public Hashtable<ClassDescriptor, Hashtable> getOptionalTaskDescriptors(){
32 return optionaltaskdescriptors;
35 /*Structure that stores a possible optional
36 task which would be safe to execute and
37 the possible flagstates the object could
38 be in before executing the task during an
39 execution without failure*/
42 public SafetyAnalysis(Hashtable executiongraph, State state, TaskAnalysis taskanalysis){
43 this.executiongraph = executiongraph;
44 this.safeexecution = new Hashtable();
45 this.reducedgraph = new Hashtable();
47 this.taskanalysis = taskanalysis;
48 this.optionaltaskdescriptors = new Hashtable();
51 /*finds the the source node in the execution graph*/
52 private EGTaskNode findSourceNode(Vector nodes){
53 for(Iterator it = nodes.iterator(); it.hasNext();){
54 EGTaskNode tn = (EGTaskNode)it.next();
62 /*returns the nodes corresponding to the tasks
63 that can fire with the object in flagstate
65 private Vector findEGTaskNode(String previousflagstate, Vector nodes){
66 Vector tns = new Vector();
67 for(Iterator it = nodes.iterator(); it.hasNext();){
68 EGTaskNode tn = (EGTaskNode)it.next();
69 if(tn.getFSName().compareTo(previousflagstate)==0)
74 else if (tns.size() > 1){
75 for(Iterator it = tns.iterator(); it.hasNext();){
76 EGTaskNode tn = (EGTaskNode)it.next();
83 /*returns the executiongraph corresponding to the classname*/
84 private Vector getConcernedClass( String classname ){
85 Enumeration e = executiongraph.keys();
86 while( e.hasMoreElements() ){
87 ClassDescriptor cd = (ClassDescriptor)e.nextElement();
88 if (classname.compareTo(cd.getSymbol())==0)
89 return (Vector)executiongraph.get(cd);
94 /*Actual method used by the compiler.
95 It computes the analysis for every
96 possible flagstates of every classes*/
97 public void buildPath() throws java.io.IOException {
98 /*Explore the taskanalysis structure*/
99 System.out.println("------- ANALYSING OPTIONAL TASKS -------");
100 Enumeration e=taskanalysis.flagstates.keys();
102 while (e.hasMoreElements()) {
103 System.out.println("\nAnalysing class :");
104 processedclass=(ClassDescriptor)e.nextElement();
105 classname = processedclass.getSymbol();
106 Hashtable newhashtable = new Hashtable();
107 optionaltaskdescriptors.put(processedclass, newhashtable);
108 Hashtable cdhashtable = new Hashtable();
110 System.out.println("\t"+classname+ "\n");
111 //get the graph result of executiongraph class
112 Vector nodes = new Vector();
113 nodes = getConcernedClass( classname );
115 System.out.println("Impossible to find "+classname+". Unexpected.");
118 else if(nodes.size()==0){
119 System.out.println("Nothing to do");
124 EGTaskNode sourcenode = findSourceNode(nodes);
125 doGraphMarking(sourcenode);
126 createDOTFile( classname );
127 reducedgraph.clear();
129 Collection fses = ((Hashtable)taskanalysis.flagstates.get(processedclass)).values();
130 Iterator itfses = fses.iterator();
131 while (itfses.hasNext()) {
132 FlagState fs = (FlagState)itfses.next();
133 Hashtable fsresult = new Hashtable();
134 //get the tasknodes possible to execute with the flagstate before failure
135 HashSet tempnodes = new HashSet();
136 Vector tns = new Vector();
137 System.out.println("Analysing "+fs.getTextLabel());
138 tns = findEGTaskNode(fs.getTextLabel(), nodes);
140 System.out.println("\tNo task corresponding, terminal FS");
143 System.out.println("\tProcessing...");
145 //compute the result for all the nodes contained in tns.
146 //return the intersection of tns that are the same task and union for others.
148 HashSet availabletasks = new HashSet();
149 availabletasks = computeTns(tns);
151 //removeDoubles(availabletasks);
153 for(Iterator it = availabletasks.iterator(); it.hasNext();){
154 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)it.next();
155 resultingFS(otd, classname);
158 cdhashtable.put(fs, availabletasks);
161 safeexecution.put(processedclass, cdhashtable);
164 putinoptionaltaskdescriptors();
170 private void putinoptionaltaskdescriptors(){
171 Enumeration e = safeexecution.keys();
172 while (e.hasMoreElements()) {
173 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
174 optionaltaskdescriptors.get(cdtemp).clear();
175 Hashtable hashtbtemp = safeexecution.get(cdtemp);
176 Enumeration fses = hashtbtemp.keys();
177 while(fses.hasMoreElements()){
178 FlagState fs = (FlagState)fses.nextElement();
179 HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
180 for(Iterator otd_it = availabletasks.iterator(); otd_it.hasNext();){
181 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
182 optionaltaskdescriptors.get(cdtemp).put(otd, otd);
188 private void printTEST(){
190 Enumeration e = safeexecution.keys();
191 while (e.hasMoreElements()) {
192 ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
193 System.out.println("\nTesting class : "+cdtemp.getSymbol()+"\n");
194 Hashtable hashtbtemp = safeexecution.get(cdtemp);
195 Enumeration fses = hashtbtemp.keys();
196 while(fses.hasMoreElements()){
197 FlagState fs = (FlagState)fses.nextElement();
198 System.out.println("\t"+fs.getTextLabel()+"\n\tSafe tasks to execute :\n");
199 HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
200 for(Iterator otd_it = availabletasks.iterator(); otd_it.hasNext();){
201 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
202 System.out.println("\t\tTASK "+otd.td.getSymbol()+" UID : "+otd.getuid()+"\n");
203 System.out.println("\t\tDepth : "+otd.depth);
204 System.out.println("\t\twith flags :");
205 for(Iterator myfses = otd.flagstates.iterator(); myfses.hasNext();){
206 System.out.println("\t\t\t"+((FlagState)myfses.next()).getTextLabel());
208 System.out.println("\t\tand exitflags :");
209 for(Iterator fseshash = otd.exitfses.iterator(); fseshash.hasNext();){
210 HashSet temphs = (HashSet)fseshash.next();
211 System.out.println("");
212 for(Iterator exfses = temphs.iterator(); exfses.hasNext();){
213 System.out.println("\t\t\t"+((FlagState)exfses.next()).getTextLabel());
216 Predicate predicate = otd.predicate;
217 System.out.println("\t\tPredicate constains :");
218 Collection c = predicate.vardescriptors.values();
219 for(Iterator varit = c.iterator(); varit.hasNext();){
220 VarDescriptor vard = (VarDescriptor)varit.next();
221 System.out.println("\t\t\tClass "+vard.getType().getClassDesc().getSymbol());
223 System.out.println("\t\t------------");
227 System.out.println("\n\n\n\tOptionaltaskdescriptors contains : ");
228 Collection c_otd = optionaltaskdescriptors.get(cdtemp).values();
229 for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
230 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
231 System.out.println("\t\tTASK "+otd.td.getSymbol()+" UID : "+otd.getuid()+"\n");
232 System.out.println("\t\tDepth : "+otd.depth);
233 System.out.println("\t\twith flags :");
234 for(Iterator myfses = otd.flagstates.iterator(); myfses.hasNext();){
235 System.out.println("\t\t\t"+((FlagState)myfses.next()).getTextLabel());
237 System.out.println("\t\tand exitflags :");
238 for(Iterator fseshash = otd.exitfses.iterator(); fseshash.hasNext();){
239 HashSet temphs = (HashSet)fseshash.next();
240 System.out.println("");
241 for(Iterator exfses = temphs.iterator(); exfses.hasNext();){
242 System.out.println("\t\t\t"+((FlagState)exfses.next()).getTextLabel());
245 Predicate predicate = otd.predicate;
246 System.out.println("\t\tPredicate contains :");
247 Collection c = predicate.vardescriptors.values();
248 for(Iterator varit = c.iterator(); varit.hasNext();){
249 VarDescriptor vard = (VarDescriptor)varit.next();
250 System.out.println("\t\t\tClass "+vard.getType().getClassDesc().getSymbol());
251 HashSet temphash = predicate.flags.get(vard.getName());
252 if(temphash == null) System.out.println("null hashset");
253 else System.out.println("\t\t\t"+temphash.size()+" flag(s)");
256 System.out.println("\t\t------------");
263 /*Marks the executiongraph :
268 private void doGraphMarking(EGTaskNode extremity) throws java.io.IOException{
269 //detects if there is a loop or no more nodes to explore
270 if (extremity.isMarked() || !((Iterator)extremity.edges()).hasNext()){
271 if (!((Iterator)extremity.edges()).hasNext()) extremity.mark();
272 reducedgraph.put(extremity.getuid(), extremity);
277 reducedgraph.put(extremity.getuid(), extremity);
279 //calls doGraphMarking recursively with the next nodes as params
280 for( Iterator it = extremity.edges(); it.hasNext(); ){
281 EGEdge edge = (EGEdge)it.next();
282 doGraphMarking((EGTaskNode)edge.getTarget());
287 private void process(EGTaskNode tn){
290 testIfNextIsSelfLoop(tn);
295 private void testIfOptional(EGTaskNode tn){
296 for(Iterator edges = tn.edges(); edges.hasNext();){
297 EGEdge edge = (EGEdge)edges.next();
298 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
299 if (nexttn.getTD()!=null)
300 if(nexttn.getTD().isOptional(classname))
301 nexttn.setOptional();
305 private void testIfMultiple(EGTaskNode tn){
306 for(Iterator edges = tn.edges(); edges.hasNext();){
307 EGEdge edge = (EGEdge)edges.next();
308 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
309 if (nexttn.getTD() == null ) return;//to be fixed
310 if( nexttn.getTD().numParameters() > 1 ){
311 nexttn.setMultipleParams();
316 //maybe a little bug to fix
317 private void testIfRuntime(EGTaskNode tn){
318 for(Iterator edges = tn.edges(); edges.hasNext();){
319 EGEdge edge = (EGEdge)edges.next();
320 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
321 if( ((String)nexttn.getName()).compareTo("Runtime") == 0 )
326 /*That correspond to the case where it is
327 not possible for us to choose a path of
328 execution. The optional task has to be
329 present in all the possible executions
330 at this point. So we mark the node as an
332 private void testIfAND(EGTaskNode tn){
333 Vector vtemp = new Vector();
334 Vector tomark = new Vector();
335 for(Iterator edges = tn.edges(); edges.hasNext();){
336 EGEdge edge = (EGEdge)edges.next();
337 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
339 for (Iterator it = vtemp.iterator(); it.hasNext();){
340 EGTaskNode nexttn2 = (EGTaskNode)it.next();
341 if (nexttn.getName()==nexttn2.getName()){
347 if (contains == 0) vtemp.add(nexttn);
350 for(Iterator it2 = tomark.iterator(); it2.hasNext();)
351 ((EGTaskNode)it2.next()).setAND();
354 //maybe little bug to fix
355 private void testIfNextIsSelfLoop(EGTaskNode tn){
356 for(Iterator edges = tn.edges(); edges.hasNext();){
357 EGEdge edge = (EGEdge)edges.next();
358 EGTaskNode nexttn = (EGTaskNode)edge.getTarget();
359 if(nexttn.isSelfLoop()) nexttn.setAND();
364 /*recursive method that returns a set of OptionalTaskDescriptors
365 The computation basically consist in returning the
366 intersection or union of sets depending on the nature
367 of the node : OR -> UNION
369 The method also looks for tag changes.
371 private HashSet determineIfIsSafe(EGTaskNode tn, int depth, HashSet visited, Predicate predicate){
372 Predicate temppredicate = new Predicate();
373 if(tn == null) return null;
376 HashSet temp = new HashSet();
377 if( tn.isMultipleParams() ){
378 if( goodMultiple(tn) ){
379 temppredicate = combinePredicates(predicate, returnPredicate(tn));
380 System.out.println("Good multiple, Optional "+tn.getName());
384 else temppredicate = combinePredicates(temppredicate, predicate);
385 //if the tn is optional and there is no more nodes/presence of a loop
386 //create the OptionalTaskDescriptor and return it as a singleton.
387 if( !((Iterator)tn.edges()).hasNext() || tn.isSelfLoop()){
388 HashSet fstemp = new HashSet();
389 fstemp.add(tn.getFS());
390 OptionalTaskDescriptor otd = new OptionalTaskDescriptor(tn.getTD(), fstemp, depth, temppredicate);
391 if(optionaltaskdescriptors.get(processedclass).get(otd)!=null){
392 otd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(otd);
394 else optionaltaskdescriptors.get(processedclass).put(otd, otd);
398 else if(visited.contains(tn)){
401 //else compute the edges, create the OptionalTaskDescriptor and add it to the set.
403 int newdepth = depth + 1;
405 HashSet newhashset = new HashSet(visited);
406 HashSet fstemp = new HashSet();
407 fstemp.add(tn.getFS());
408 OptionalTaskDescriptor otd = new OptionalTaskDescriptor(tn.getTD(), fstemp, depth, temppredicate);
409 if(optionaltaskdescriptors.get(processedclass).get(otd)!=null){
410 otd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(otd);
412 else optionaltaskdescriptors.get(processedclass).put(otd, otd);
413 temp = computeEdges(tn, newdepth, newhashset, temppredicate);
419 HashSet temp = new HashSet();
420 if( tn.isMultipleParams() ){
421 if( goodMultiple(tn) ){
422 temppredicate = combinePredicates(predicate, returnPredicate(tn));
423 System.out.println("Good multiple, not Optional "+tn.getName());
426 System.out.println("Bad multiple, not Optional "+tn.getName());
430 else temppredicate = combinePredicates(temppredicate, predicate);
431 //if not optional but terminal just return an empty set.
432 if( !((Iterator)tn.edges()).hasNext() || visited.contains(tn) || tn.isSelfLoop()){
435 //if not terminal return the computation of the edges.
437 int newdepth = depth + 1;
439 HashSet newhashset = new HashSet(visited);
440 return computeEdges(tn, newdepth, newhashset, temppredicate);
444 //if there has been a tag change return an empty set.
446 HashSet temp = new HashSet();
451 private boolean goodMultiple(EGTaskNode tn){
452 TaskDescriptor td = tn.getTD();
453 HashSet classes = new HashSet();
454 for(int i = 0 ; i<td.numParameters(); i++){
455 ClassDescriptor cd = td.getParamType(i).getClassDesc();
456 if(cd.getSymbol().compareTo(classname)!=0)
461 Stack stack = new Stack();
462 FlatMethod fm = state.getMethodFlat(td);
463 FlatNode fn = (FlatNode)fm;
465 Stack nodestack=new Stack();
466 HashSet discovered=new HashSet();
470 //Iterating through the nodes
471 while(!nodestack.isEmpty()) {
472 FlatNode fn1 = (FlatNode) nodestack.pop();
473 if (fn1.kind()==FKind.FlatFlagActionNode) {
474 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
475 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
476 for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) {
477 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
478 TempDescriptor tempd = tfp.getTemp();
479 if (classes.contains((ClassDescriptor)((TypeDescriptor)tempd.getType()).getClassDesc()))
480 return false;//return false if a taskexit modifies one of the other parameters
482 continue; // avoid queueing the return node if reachable
485 /* Queue other nodes past this one */
486 for(int i=0;i<fn1.numNext();i++) {
487 FlatNode fnext=fn1.getNext(i);
488 if (!discovered.contains(fnext)) {
489 discovered.add(fnext);
490 nodestack.push(fnext);
498 private Predicate returnPredicate(EGTaskNode tn){
499 Predicate result = new Predicate();
500 TaskDescriptor td = tn.getTD();
501 for(int i=0; i<td.numParameters(); i++){
502 TypeDescriptor typed = td.getParamType(i);
503 if(((ClassDescriptor)typed.getClassDesc()).getSymbol().compareTo(classname)!=0){
504 VarDescriptor vd = td.getParameter(i);
505 result.vardescriptors.put(vd.getName(), vd);
506 HashSet flaglist = new HashSet();
507 flaglist.add((FlagExpressionNode)td.getFlag(vd));
508 result.flags.put( vd.getName(), flaglist);
509 if((TagExpressionList)td.getTag(vd) != null)
510 result.tags.put( vd.getName(), (TagExpressionList)td.getTag(vd));
516 /*check if there has been a tag Change*/
517 private boolean tagChange(EGTaskNode tn){
518 if(tn.getTD() == null) return false;//to be fixed
519 FlatMethod fm = state.getMethodFlat(tn.getTD());
520 FlatNode fn = (FlatNode)fm;
522 Stack nodestack=new Stack();
523 HashSet discovered=new HashSet();
527 //Iterating through the nodes
528 while(!nodestack.isEmpty()) {
529 FlatNode fn1 = (FlatNode) nodestack.pop();
530 if (fn1.kind()==FKind.FlatFlagActionNode) {
531 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
532 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
533 Iterator it_ttp=ffan.getTempTagPairs();
534 if(it_ttp.hasNext()){
535 System.out.println("Tag change detected in Task "+tn.getName());
538 else continue; // avoid queueing the return node if reachable
542 /* Queue other nodes past this one */
543 for(int i=0;i<fn1.numNext();i++) {
544 FlatNode fnext=fn1.getNext(i);
545 if (!discovered.contains(fnext)) {
546 discovered.add(fnext);
547 nodestack.push(fnext);
555 private HashSet computeEdges(EGTaskNode tn, int depth, HashSet visited, Predicate predicate){
556 Hashtable andlist = new Hashtable();
557 Vector orlist = new Vector();
558 for(Iterator edges = tn.edges(); edges.hasNext();){
559 EGTaskNode tntemp = (EGTaskNode)((EGEdge)edges.next()).getTarget();
560 if(tntemp.type() == OR) orlist.add(tntemp);
561 else if(tntemp.type() == AND){
562 if(andlist.containsKey(tntemp.getName())){
563 ((Vector)andlist.get(tntemp.getName())).add(tntemp);}
565 Vector vector = new Vector();
567 andlist.put(tntemp.getName(), vector);
572 return (createUnion(computeOrVector(orlist, depth, visited, predicate), computeAndList(andlist, depth, visited, predicate)));
575 private HashSet computeTns(Vector tns){
576 Hashtable andlist = new Hashtable();
577 Vector orlist = new Vector();
578 for(Iterator nodes = tns.iterator(); nodes.hasNext();){
579 EGTaskNode tntemp = (EGTaskNode)nodes.next();
580 if(tntemp.type() == OR) orlist.add(tntemp);
581 else if(tntemp.type() == AND){
582 if(andlist.containsKey(tntemp.getName())){
583 ((Vector)andlist.get(tntemp.getName())).add(tntemp);}
585 Vector vector = new Vector();
587 andlist.put(tntemp.getName(), vector);
592 return (createUnion(computeOrVector(orlist, 0), computeAndList(andlist, 0)));
596 private HashSet computeOrVector( Vector orlist, int depth, HashSet visited, Predicate predicate){
597 if(orlist.isEmpty()){
598 HashSet temp = new HashSet();
602 HashSet temp = new HashSet();
603 for(Iterator tns = orlist.iterator(); tns.hasNext();){
604 EGTaskNode tn = (EGTaskNode)tns.next();
605 temp = createUnion(determineIfIsSafe(tn, depth, visited, predicate), temp);
612 private HashSet computeOrVector( Vector orlist, int depth){
613 if(orlist.isEmpty()){
614 HashSet temp = new HashSet();
618 HashSet temp = new HashSet();
619 for(Iterator tns = orlist.iterator(); tns.hasNext();){
620 EGTaskNode tn = (EGTaskNode)tns.next();
621 HashSet visited = new HashSet();
622 Predicate predicate = new Predicate();
623 temp = createUnion(determineIfIsSafe(tn, depth, visited, predicate), temp);
630 private HashSet computeAndList(Hashtable andlist, int depth, HashSet visited, Predicate predicate){
631 if( andlist.isEmpty()){
632 HashSet temp = new HashSet();
636 HashSet temp = new HashSet();
637 Collection c = andlist.values();
638 for(Iterator vectors = c.iterator(); vectors.hasNext();){
639 Vector vector = (Vector)vectors.next();
640 temp = createUnion(computeAndVector(vector, depth, visited, predicate), temp);
647 private HashSet computeAndList(Hashtable andlist, int depth){
648 if( andlist.isEmpty()){
649 HashSet temp = new HashSet();
653 HashSet temp = new HashSet();
654 Collection c = andlist.values();
655 for(Iterator vectors = c.iterator(); vectors.hasNext();){
656 Vector vector = (Vector)vectors.next();
657 temp = createUnion(computeAndVector(vector, depth), temp);
664 private HashSet computeAndVector(Vector vector, int depth, HashSet visited, Predicate predicate){
665 HashSet temp = new HashSet();
667 for(Iterator tns = vector.iterator(); tns.hasNext();){
668 EGTaskNode tn = (EGTaskNode)tns.next();
671 temp = determineIfIsSafe(tn, depth, visited, predicate);
674 temp = createIntersection(determineIfIsSafe(tn, depth, visited, predicate), temp);
680 private HashSet computeAndVector(Vector vector, int depth){
681 HashSet temp = new HashSet();
683 for(Iterator tns = vector.iterator(); tns.hasNext();){
684 EGTaskNode tn = (EGTaskNode)tns.next();
687 HashSet visited = new HashSet();
688 Predicate predicate = new Predicate();
689 temp = determineIfIsSafe(tn, depth, visited, predicate);
692 HashSet visited = new HashSet();
693 Predicate predicate = new Predicate();
694 temp = createIntersection(determineIfIsSafe(tn, depth, visited, predicate), temp);
700 private HashSet createUnion( HashSet A, HashSet B){
707 private HashSet createIntersection( HashSet A, HashSet B){
708 HashSet result = new HashSet();
709 //HashSet processed = new HashSet();
710 for(Iterator b_it = B.iterator(); b_it.hasNext();){
711 OptionalTaskDescriptor otd_b = (OptionalTaskDescriptor)b_it.next();
712 for(Iterator a_it = A.iterator(); a_it.hasNext();){
713 OptionalTaskDescriptor otd_a = (OptionalTaskDescriptor)a_it.next();
714 if(((String)otd_a.td.getSymbol()).compareTo((String)otd_b.td.getSymbol())==0){
715 //processed.add(otd_a);
716 //processed.add(otd_b);
718 HashSet newfs = new HashSet();
719 newfs.addAll(otd_a.flagstates);
720 newfs.addAll(otd_b.flagstates);
721 int newdepth = (otd_a.depth < otd_b.depth) ? otd_a.depth : otd_b.depth;
722 OptionalTaskDescriptor newotd = new OptionalTaskDescriptor(otd_b.td, newfs, newdepth, combinePredicates(otd_a.predicate, otd_b.predicate));
723 if(optionaltaskdescriptors.get(processedclass).get(newotd)!=null){
724 //System.out.println("OTD found");
725 System.out.println("before "+newotd.getuid());
726 newotd = (OptionalTaskDescriptor)((Hashtable)optionaltaskdescriptors.get(processedclass)).get(newotd);
727 System.out.println("after "+newotd.getuid());
729 else optionaltaskdescriptors.get(processedclass).put(newotd, newotd);
735 /* for(Iterator a_it = A.iterator(); a_it.hasNext();){
736 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)a_it.next();
737 if(!processed.contains(otd))
738 optionaltaskdescriptors.get(processedclass).remove(otd);
740 for(Iterator b_it = B.iterator(); b_it.hasNext();){
741 OptionalTaskDescriptor otd = (OptionalTaskDescriptor)b_it.next();
742 if(!processed.contains(otd))
743 optionaltaskdescriptors.get(processedclass).remove(otd);
748 private Predicate combinePredicates(Predicate A, Predicate B){
749 Predicate result = new Predicate();
750 result.vardescriptors.putAll(A.vardescriptors);
751 result.flags.putAll(A.flags);
752 result.tags.putAll(A.tags);
753 Collection c = B.vardescriptors.values();
754 for(Iterator varit = c.iterator(); varit.hasNext();){//maybe change that
755 VarDescriptor vd = (VarDescriptor)varit.next();
756 if(result.vardescriptors.containsKey(vd.getName())) System.out.println("Already in ");
758 //System.out.println("Not already in...");
759 result.vardescriptors.put(vd.getName(), vd);
762 Collection vardesc = result.vardescriptors.values();
763 for(Iterator varit = vardesc.iterator(); varit.hasNext();){
764 VarDescriptor vd = (VarDescriptor)varit.next();
765 HashSet bflags = B.flags.get(vd.getName());
766 if( bflags == null ){
767 //System.out.println("not in B");
771 if (result.flags.containsKey(vd.getName())) ((HashSet)result.flags.get(vd.getName())).addAll(bflags);
772 else result.flags.put(vd.getName(), bflags);
774 TagExpressionList btags = B.tags.get(vd.getName());
776 if (result.tags.containsKey(vd.getName())) System.out.println("Tag found but there should be nothing to do because same tag");
777 else result.tags.put(vd.getName(), btags);
784 /*Thoose two tasks create the dot file named markedgraph.dot */
786 private void createDOTFile(String classname) throws java.io.IOException {
787 Collection v = reducedgraph.values();
788 java.io.PrintWriter output;
789 File dotfile_flagstates= new File("markedgraph_"+classname+".dot");
790 FileOutputStream dotstream=new FileOutputStream(dotfile_flagstates,true);
791 output = new java.io.PrintWriter(dotstream, true);
792 output.println("digraph dotvisitor {");
793 output.println("\tnode [fontsize=10,height=\"0.1\", width=\"0.1\"];");
794 output.println("\tedge [fontsize=6];");
796 output.println("}\n");
799 private void traverse(java.io.PrintWriter output, Collection v) {
802 for(Iterator it1 = v.iterator(); it1.hasNext();){
803 tn = (EGTaskNode)it1.next();
804 output.println("\t"+tn.getLabel()+" [label=\""+tn.getTextLabel()+"\"");
805 if (tn.isOptional()){
806 if (tn.isMultipleParams()) output.println(", shape = tripleoctagon");
807 else output.println(", shape=doubleoctagon");
809 else if (tn.isMultipleParams()) output.println(", shape=octagon");
810 if (tn.type()==AND) output.println(", color=blue");
811 output.println("];");
813 for(Iterator it2 = tn.edges();it2.hasNext();){
814 EGTaskNode tn2 = (EGTaskNode)((Edge)it2.next()).getTarget();
815 output.println("\t"+tn.getLabel()+" -> "+tn2.getLabel()+";");
821 /* returns a set of the possible sets of flagstates
822 resulting from the execution of the optional task.
823 To do it with have to look for TaskExit FlatNodes
826 private void resultingFS(OptionalTaskDescriptor otd, String classname){
827 Stack stack = new Stack();
828 HashSet result = new HashSet();
829 FlatMethod fm = state.getMethodFlat((TaskDescriptor)otd.td);
830 FlatNode fn = (FlatNode)fm;
832 Stack nodestack=new Stack();
833 HashSet discovered=new HashSet();
837 //Iterating through the nodes
838 while(!nodestack.isEmpty()) {
839 FlatNode fn1 = (FlatNode) nodestack.pop();
840 if (fn1.kind()==FKind.FlatFlagActionNode) {
841 FlatFlagActionNode ffan=(FlatFlagActionNode)fn1;
842 if (ffan.getTaskType() == FlatFlagActionNode.TASKEXIT) {
844 //System.out.println("TASKEXIT");
846 HashSet tempset = new HashSet();
847 for(Iterator it_fs = otd.flagstates.iterator(); it_fs.hasNext();){
848 FlagState fstemp = (FlagState)it_fs.next();
849 for(Iterator it_tfp=ffan.getTempFlagPairs();it_tfp.hasNext();) {
850 TempFlagPair tfp=(TempFlagPair)it_tfp.next();
851 TempDescriptor td = tfp.getTemp();
852 if (((String)((ClassDescriptor)((TypeDescriptor)td.getType()).getClassDesc()).getSymbol()).compareTo(classname)==0){
853 fstemp=fstemp.setFlag(tfp.getFlag(),ffan.getFlagChange(tfp));
856 //System.out.println("new flag : "+fstemp.getTextLabel());
860 continue; // avoid queueing the return node if reachable
862 }else if (fn1.kind()==FKind.FlatReturnNode) {
864 //System.out.println("RETURN NODE REACHABLE WITHOUT TASKEXITS");
866 result.add(otd.flagstates);
869 /* Queue other nodes past this one */
870 for(int i=0;i<fn1.numNext();i++) {
871 FlatNode fnext=fn1.getNext(i);
872 if (!discovered.contains(fnext)) {
873 discovered.add(fnext);
874 nodestack.push(fnext);