Bug fixed in BuildCode.
[IRC.git] / Robust / src / IR / Flat / BuildCode.java
1 package IR.Flat;
2 import IR.Tree.FlagExpressionNode;
3 import IR.Tree.DNFFlag;
4 import IR.Tree.DNFFlagAtom;
5 import IR.Tree.TagExpressionList;
6 import IR.*;
7 import java.util.*;
8 import java.io.*;
9 import Util.Relation;
10 import Analysis.TaskStateAnalysis.FlagState;
11 import Analysis.TaskStateAnalysis.OptionalTaskDescriptor;
12 import Analysis.TaskStateAnalysis.Predicate;
13 import Analysis.Locality.LocalityAnalysis;
14 import Analysis.Locality.LocalityBinding;
15
16 public class BuildCode {
17     State state;
18     Hashtable temptovar;
19     Hashtable paramstable;
20     Hashtable tempstable;
21     Hashtable fieldorder;
22     Hashtable flagorder;
23     int tag=0;
24     String localsprefix="___locals___";
25     String paramsprefix="___params___";
26     String oidstr="___nextobject___";
27     String nextobjstr="___nextobject___";
28     String localcopystr="___localcopy___";
29     public static boolean GENERATEPRECISEGC=false;
30     public static String PREFIX="";
31     public static String arraytype="ArrayObject";
32     Virtual virtualcalls;
33     TypeUtil typeutil;
34     private int maxtaskparams=0;
35     private int maxcount=0;
36     ClassDescriptor[] cdarray;
37     TypeDescriptor[] arraytable;
38     LocalityAnalysis locality;
39     Hashtable<TempDescriptor, TempDescriptor> backuptable;
40
41     public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil) {
42         state=st;
43         this.temptovar=temptovar;
44         paramstable=new Hashtable();    
45         tempstable=new Hashtable();
46         fieldorder=new Hashtable();
47         flagorder=new Hashtable();
48         this.typeutil=typeutil;
49         virtualcalls=new Virtual(state);
50     }
51
52     public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality) {
53         this(st, temptovar, typeutil);
54         this.locality=locality;
55         this.backuptable=new Hashtable<TempDescriptor, TempDescriptor>();
56     }
57
58     /** The buildCode method outputs C code for all the methods.  The Flat
59      * versions of the methods must already be generated and stored in
60      * the State object. */
61
62     public void buildCode() {
63         /* Create output streams to write to */
64         PrintWriter outclassdefs=null;
65         PrintWriter outstructs=null;
66         PrintWriter outrepairstructs=null;
67         PrintWriter outmethodheader=null;
68         PrintWriter outmethod=null;
69         PrintWriter outvirtual=null;
70         PrintWriter outtask=null;
71         PrintWriter outtaskdefs=null;
72         PrintWriter outoptionalarrays=null;
73         PrintWriter optionalheaders=null;
74
75         try {
76             outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
77             outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
78             outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
79             outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
80             outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
81             if (state.TASK) {
82                 outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
83                 outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
84                 if (state.OPTIONAL){
85                     outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
86                     optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
87                 } 
88             }
89             if (state.structfile!=null) {
90                 outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
91             }
92         } catch (Exception e) {
93             e.printStackTrace();
94             System.exit(-1);
95         }
96
97         /* Build the virtual dispatch tables */
98         buildVirtualTables(outvirtual);
99
100         /* Output includes */
101         outmethodheader.println("#ifndef METHODHEADERS_H");
102         outmethodheader.println("#define METHODHEADERS_H");
103         outmethodheader.println("#include \"structdefs.h\"");
104
105         /* Output Structures */
106         outputStructs(outstructs);
107
108         // Output the C class declarations
109         // These could mutually reference each other
110         outputClassDeclarations(outclassdefs);
111
112         // Output function prototypes and structures for parameters
113         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
114         while(it.hasNext()) {
115             ClassDescriptor cn=(ClassDescriptor)it.next();
116             generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
117         }
118         outclassdefs.close();
119
120         if (state.TASK) {
121             /* Map flags to integers */
122             /* The runtime keeps track of flags using these integers */
123             it=state.getClassSymbolTable().getDescriptorsIterator();
124             while(it.hasNext()) {
125                 ClassDescriptor cn=(ClassDescriptor)it.next();
126                 mapFlags(cn);
127             }
128             /* Generate Tasks */
129             generateTaskStructs(outstructs, outmethodheader);
130
131             /* Outputs generic task structures if this is a task
132                program */
133             outputTaskTypes(outtask);
134         }
135
136         /* Build the actual methods */
137         outputMethods(outmethod);
138
139         if (state.TASK) {
140             /* Output code for tasks */
141             outputTaskCode(outtaskdefs, outmethod);
142             outtaskdefs.close();
143             /* Record maximum number of task parameters */
144             outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
145         } else if (state.main!=null) {
146             /* Generate main method */
147             outputMainMethod(outmethod);
148         }
149         
150         /* Generate information for task with optional parameters */
151         if (state.TASK&&state.OPTIONAL){
152             generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
153             outoptionalarrays.close();
154         } 
155
156         /* Output structure definitions for repair tool */
157         if (state.structfile!=null) {
158             buildRepairStructs(outrepairstructs);
159             outrepairstructs.close();
160         }
161
162         /* Close files */
163         outmethodheader.println("#endif");
164         outmethodheader.close();
165         outmethod.close();
166         outstructs.println("#endif");
167         outstructs.close();
168     }
169
170     /* This code just generates the main C method for java programs.
171      * The main C method packs up the arguments into a string array
172      * and passes it to the java main method. */
173
174     private void outputMainMethod(PrintWriter outmethod) {
175         outmethod.println("int main(int argc, const char *argv[]) {");
176         outmethod.println("  int i;");
177         if (GENERATEPRECISEGC) {
178             outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
179         } else {
180             outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
181         }
182         if (state.THREAD) {
183             outmethod.println("initializethreads();");
184         }
185         outmethod.println("  for(i=1;i<argc;i++) {");
186         outmethod.println("    int length=strlen(argv[i]);");
187         if (GENERATEPRECISEGC) {
188             outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
189         } else {
190             outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
191         }
192         outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
193         outmethod.println("  }");
194         
195         
196         MethodDescriptor md=typeutil.getMain();
197         ClassDescriptor cd=typeutil.getMainClass();
198         
199         outmethod.println("   {");
200         if (GENERATEPRECISEGC) {
201             outmethod.print("       struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
202             outmethod.println("1, NULL,"+"stringarray};");
203             outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
204         } else
205             outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
206         outmethod.println("   }");
207         
208         if (state.THREAD) {
209             outmethod.println("pthread_mutex_lock(&gclistlock);");
210             outmethod.println("threadcount--;");
211             outmethod.println("pthread_cond_signal(&gccond);");
212             outmethod.println("pthread_mutex_unlock(&gclistlock);");
213             outmethod.println("pthread_exit(NULL);");
214         }
215         outmethod.println("}");
216     }
217
218     /* This method outputs code for each task. */
219
220     private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod) {
221         /* Compile task based program */
222         outtaskdefs.println("#include \"task.h\"");
223         outtaskdefs.println("#include \"methodheaders.h\"");
224         Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
225         while(taskit.hasNext()) {
226             TaskDescriptor td=(TaskDescriptor)taskit.next();
227             FlatMethod fm=state.getMethodFlat(td);
228             generateFlatMethod(fm, null, outmethod);
229             generateTaskDescriptor(outtaskdefs, fm, td);
230         }
231         
232         //Output task descriptors
233         taskit=state.getTaskSymbolTable().getDescriptorsIterator();
234         outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
235         boolean first=true;
236         while(taskit.hasNext()) {
237             TaskDescriptor td=(TaskDescriptor)taskit.next();
238             if (first)
239                 first=false;
240             else
241                 outtaskdefs.println(",");
242             outtaskdefs.print("&task_"+td.getSafeSymbol());
243         }
244         outtaskdefs.println("};");
245
246         outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
247     }
248
249     /* This method outputs most of the methods.c file.  This includes
250      * some standard includes and then an array with the sizes of
251      * objets and array that stores supertype and then the code for
252      * the Java methods.. */
253
254     private void outputMethods(PrintWriter outmethod) {
255         outmethod.println("#include \"methodheaders.h\"");
256         outmethod.println("#include \"virtualtable.h\"");
257         outmethod.println("#include <runtime.h>");
258         if (state.THREAD)
259             outmethod.println("#include <thread.h>");
260         if (state.main!=null) {
261             outmethod.println("#include <string.h>");       
262         }
263         if (state.CONSCHECK) {
264             outmethod.println("#include \"checkers.h\"");
265         }
266         //Store the sizes of classes & array elements
267         generateSizeArray(outmethod);
268         
269         //Store table of supertypes
270         generateSuperTypeTable(outmethod);
271
272         //Store the layout of classes
273         generateLayoutStructs(outmethod);
274
275         /* Generate code for methods */
276         if (state.DSM) {
277             for(Iterator<LocalityBinding> lbit=locality.getLocalityBindings().iterator();lbit.hasNext();) {
278                 LocalityBinding lb=lbit.next();
279                 MethodDescriptor md=lb.getMethod();
280                 FlatMethod fm=state.getMethodFlat(md);
281                 if (!md.getModifiers().isNative()) {
282                     generateFlatMethod(fm, lb, outmethod);
283                 }
284             }
285         } else {
286             Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
287             while(classit.hasNext()) {
288                 ClassDescriptor cn=(ClassDescriptor)classit.next();
289                 Iterator methodit=cn.getMethods();
290                 while(methodit.hasNext()) {
291                     /* Classify parameters */
292                     MethodDescriptor md=(MethodDescriptor)methodit.next();
293                     FlatMethod fm=state.getMethodFlat(md);
294                     if (!md.getModifiers().isNative())
295                         generateFlatMethod(fm, null, outmethod);
296                 }
297             }
298         } 
299     }
300
301     private void outputStructs(PrintWriter outstructs) {
302         outstructs.println("#ifndef STRUCTDEFS_H");
303         outstructs.println("#define STRUCTDEFS_H");
304         outstructs.println("#include \"classdefs.h\"");
305
306         /* Output #defines that the runtime uses to determine type
307          * numbers for various objects it needs */
308
309         outstructs.println("#define STRINGARRAYTYPE "+
310                            (state.getArrayNumber(
311                                                  (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
312
313         outstructs.println("#define OBJECTARRAYTYPE "+
314                            (state.getArrayNumber(
315                                                  (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
316
317
318         outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
319         outstructs.println("#define CHARARRAYTYPE "+
320                            (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
321
322         outstructs.println("#define BYTEARRAYTYPE "+
323                            (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses()));
324
325         outstructs.println("#define BYTEARRAYARRAYTYPE "+
326                            (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
327         
328         outstructs.println("#define NUMCLASSES "+state.numClasses());
329         if (state.TASK) {
330             outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
331             outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
332             outstructs.println("#define TAGARRAYTYPE "+
333                                (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
334         }
335     }
336
337     private void outputClassDeclarations(PrintWriter outclassdefs) {
338         if (state.THREAD)
339             outclassdefs.println("#include <pthread.h>");
340         if(state.OPTIONAL)
341             outclassdefs.println("#include \"optionalstruct.h\"");
342         outclassdefs.println("struct "+arraytype+";");
343         /* Start by declaring all structs */
344         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
345         while(it.hasNext()) {
346             ClassDescriptor cn=(ClassDescriptor)it.next();
347             outclassdefs.println("struct "+cn.getSafeSymbol()+";");
348         }
349         outclassdefs.println("");
350         //Print out definition for array type
351         outclassdefs.println("struct "+arraytype+" {");
352         outclassdefs.println("  int type;");
353         if (state.THREAD) {
354             outclassdefs.println("  pthread_t tid;");
355             outclassdefs.println("  void * lockentry;");
356             outclassdefs.println("  int lockcount;");
357         }
358         if (state.TASK) {
359             outclassdefs.println("  int flag;");
360             outclassdefs.println("  void * flagptr;");
361             if(state.OPTIONAL){
362                 outclassdefs.println("  int failedstatus;");
363                 outclassdefs.println("  int hashcode;");
364                 outclassdefs.println("  int numexitfses;");
365                 outclassdefs.println("  int * exitfses;");
366                 outclassdefs.println("  int numotds;");
367                 outclassdefs.println("  struct optionaltaskdescriptor ** otds;");
368             }
369         }
370         printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
371         
372         outclassdefs.println("  int ___length___;");
373         outclassdefs.println("};\n");
374         outclassdefs.println("extern int classsize[];");
375         outclassdefs.println("extern int hasflags[];");
376         outclassdefs.println("extern unsigned int * pointerarray[];");
377         outclassdefs.println("extern int supertypes[];");
378     }
379
380     /** Prints out definitions for generic task structures */
381
382     private void outputTaskTypes(PrintWriter outtask) {
383         outtask.println("#ifndef _TASK_H");
384         outtask.println("#define _TASK_H");
385         outtask.println("struct parameterdescriptor {");
386         outtask.println("int type;");
387         outtask.println("int numberterms;");
388         outtask.println("int *intarray;");
389         outtask.println("void * queue;");
390         outtask.println("int numbertags;");
391         outtask.println("int *tagarray;");
392         outtask.println("};");
393         
394         outtask.println("struct taskdescriptor {");
395         outtask.println("void * taskptr;");
396         outtask.println("int numParameters;");
397         outtask.println("int numTotal;");
398         outtask.println("struct parameterdescriptor **descriptorarray;");
399         outtask.println("char * name;");
400         outtask.println("};");
401         outtask.println("extern struct taskdescriptor * taskarray[];");
402         outtask.println("extern numtasks;");
403         outtask.println("#endif");
404     }
405
406
407     private void buildRepairStructs(PrintWriter outrepairstructs) {
408         Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
409         while(classit.hasNext()) {
410             ClassDescriptor cn=(ClassDescriptor)classit.next();
411             outrepairstructs.println("structure "+cn.getSymbol()+" {");
412             outrepairstructs.println("  int __type__;");
413             if (state.TASK) {
414                 outrepairstructs.println("  int __flag__;");
415                 outrepairstructs.println("  int __flagptr__;");
416             }
417             printRepairStruct(cn, outrepairstructs);
418             outrepairstructs.println("}\n");
419         }
420         
421         for(int i=0;i<state.numArrays();i++) {
422             TypeDescriptor tdarray=arraytable[i];
423             TypeDescriptor tdelement=tdarray.dereference();
424             outrepairstructs.println("structure "+arraytype+"_"+state.getArrayNumber(tdarray)+" {");
425             outrepairstructs.println("  int __type__;");
426             printRepairStruct(typeutil.getClass(TypeUtil.ObjectClass), outrepairstructs);
427             outrepairstructs.println("  int length;");
428             /*
429               // Need to add support to repair tool for this
430               if (tdelement.isClass()||tdelement.isArray())
431                 outrepairstructs.println("  "+tdelement.getRepairSymbol()+" * elem[this.length];");
432             else
433                 outrepairstructs.println("  "+tdelement.getRepairSymbol()+" elem[this.length];");
434             */
435             outrepairstructs.println("}\n");
436         }
437     }
438
439     private void printRepairStruct(ClassDescriptor cn, PrintWriter output) {
440         ClassDescriptor sp=cn.getSuperDesc();
441         if (sp!=null)
442             printRepairStruct(sp, output);
443         
444         Vector fields=(Vector)fieldorder.get(cn);
445
446         for(int i=0;i<fields.size();i++) {
447             FieldDescriptor fd=(FieldDescriptor)fields.get(i);
448             if (fd.getType().isArray()) {
449                 output.println("  "+arraytype+"_"+ state.getArrayNumber(fd.getType()) +" * "+fd.getSymbol()+";");
450             } else if (fd.getType().isClass())
451                 output.println("  "+fd.getType().getRepairSymbol()+" * "+fd.getSymbol()+";");
452             else if (fd.getType().isFloat())
453                 output.println("  int "+fd.getSymbol()+"; /* really float */");
454             else 
455                 output.println("  "+fd.getType().getRepairSymbol()+" "+fd.getSymbol()+";");
456         }
457     }
458
459     /** This method outputs TaskDescriptor information */
460     void generateTaskDescriptor(PrintWriter output, FlatMethod fm, TaskDescriptor task) {
461         for (int i=0;i<task.numParameters();i++) {
462             VarDescriptor param_var=task.getParameter(i);
463             TypeDescriptor param_type=task.getParamType(i);
464             FlagExpressionNode param_flag=task.getFlag(param_var);
465             TagExpressionList param_tag=task.getTag(param_var);
466
467             int dnfterms;
468             if (param_flag==null) {
469                 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
470                 output.println("0x0, 0x0 };");
471                 dnfterms=1;
472             } else {
473                 DNFFlag dflag=param_flag.getDNF();
474                 dnfterms=dflag.size();
475                 
476                 Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
477                 output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
478                 for(int j=0;j<dflag.size();j++) {
479                     if (j!=0)
480                         output.println(",");
481                     Vector term=dflag.get(j);
482                     int andmask=0;
483                     int checkmask=0;
484                     for(int k=0;k<term.size();k++) {
485                         DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
486                         FlagDescriptor fd=dfa.getFlag();
487                         boolean negated=dfa.getNegated();
488                         int flagid=1<<((Integer)flags.get(fd)).intValue();
489                         andmask|=flagid;
490                         if (!negated)
491                             checkmask|=flagid;
492                     }
493                     output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
494                 }
495                 output.println("};");
496             }
497
498             output.println("int parametertag_"+i+"_"+task.getSafeSymbol()+"[]={");
499             //BUG...added next line to fix, test with any task program
500             if (param_tag!=null)
501                 for(int j=0;j<param_tag.numTags();j++) {
502                     if (j!=0)
503                         output.println(",");
504                     /* for each tag we need */
505                     /* which slot it is */
506                     /* what type it is */
507                     TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
508                     TempDescriptor tmp=param_tag.getTemp(j);
509                     int slot=fm.getTagInt(tmp);
510                     output.println(slot+", "+state.getTagId(tvd.getTag()));
511                 }
512             output.println("};");
513
514             output.println("struct parameterdescriptor parameter_"+i+"_"+task.getSafeSymbol()+"={");
515             output.println("/* type */"+param_type.getClassDesc().getId()+",");
516             output.println("/* number of DNF terms */"+dnfterms+",");
517             output.println("parameterdnf_"+i+"_"+task.getSafeSymbol()+",");
518             output.println("0,");
519             //BUG, added next line to fix and else statement...test
520             //with any task program
521             if (param_tag!=null)
522                 output.println("/* number of tags */"+param_tag.numTags()+",");
523             else
524                 output.println("/* number of tags */ 0,");
525             output.println("parametertag_"+i+"_"+task.getSafeSymbol());
526             output.println("};");
527         }
528
529
530         output.println("struct parameterdescriptor * parameterdescriptors_"+task.getSafeSymbol()+"[] = {");
531         for (int i=0;i<task.numParameters();i++) {
532             if (i!=0)
533                 output.println(",");
534             output.print("&parameter_"+i+"_"+task.getSafeSymbol());
535         }
536         output.println("};");
537
538         output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
539         output.println("&"+task.getSafeSymbol()+",");
540         output.println("/* number of parameters */" +task.numParameters() + ",");
541         int numtotal=task.numParameters()+fm.numTags();
542         output.println("/* number total parameters */" +numtotal + ",");
543         output.println("parameterdescriptors_"+task.getSafeSymbol()+",");
544         output.println("\""+task.getSymbol()+"\"");
545         output.println("};");
546     }
547
548
549     /** The buildVirtualTables method outputs the virtual dispatch
550      * tables for methods. */
551
552     private void buildVirtualTables(PrintWriter outvirtual) {
553         Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
554         while(classit.hasNext()) {
555             ClassDescriptor cd=(ClassDescriptor)classit.next();
556             if (virtualcalls.getMethodCount(cd)>maxcount)
557                 maxcount=virtualcalls.getMethodCount(cd);
558         }
559         MethodDescriptor[][] virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount];
560
561         /* Fill in virtual table */
562         classit=state.getClassSymbolTable().getDescriptorsIterator();
563         while(classit.hasNext()) {
564             ClassDescriptor cd=(ClassDescriptor)classit.next();
565             fillinRow(cd, virtualtable, cd.getId());
566         }
567
568         ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
569         Iterator arrayit=state.getArrayIterator();
570         while(arrayit.hasNext()) {
571             TypeDescriptor td=(TypeDescriptor)arrayit.next();
572             int id=state.getArrayNumber(td);
573             fillinRow(objectcd, virtualtable, id+state.numClasses());
574         }
575         
576         outvirtual.print("void * virtualtable[]={");
577         boolean needcomma=false;
578         for(int i=0;i<state.numClasses()+state.numArrays();i++) {
579             for(int j=0;j<maxcount;j++) {
580                 if (needcomma)
581                     outvirtual.print(", ");
582                 if (virtualtable[i][j]!=null) {
583                     MethodDescriptor md=virtualtable[i][j];
584                     outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
585                 } else {
586                     outvirtual.print("0");
587                 }
588                 needcomma=true;
589             }
590             outvirtual.println("");
591         }
592         outvirtual.println("};");
593         outvirtual.close();
594     }
595
596     private void fillinRow(ClassDescriptor cd, MethodDescriptor[][] virtualtable, int rownum) {
597         /* Get inherited methods */
598         if (cd.getSuperDesc()!=null)
599             fillinRow(cd.getSuperDesc(), virtualtable, rownum);
600         /* Override them with our methods */
601         for(Iterator it=cd.getMethods();it.hasNext();) {
602             MethodDescriptor md=(MethodDescriptor)it.next();
603             if (md.isStatic()||md.getReturnType()==null)
604                 continue;
605             int methodnum=virtualcalls.getMethodNumber(md);
606             virtualtable[rownum][methodnum]=md;
607         }
608     }
609
610     /** Generate array that contains the sizes of class objects.  The
611      * object allocation functions in the runtime use this
612      * information. */
613
614     private void generateSizeArray(PrintWriter outclassdefs) {
615         outclassdefs.print("int classsize[]={");
616         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
617         cdarray=new ClassDescriptor[state.numClasses()];
618         while(it.hasNext()) {
619             ClassDescriptor cd=(ClassDescriptor)it.next();
620             cdarray[cd.getId()]=cd;
621         }
622         boolean needcomma=false;
623         for(int i=0;i<state.numClasses();i++) {
624             if (needcomma)
625                 outclassdefs.print(", ");
626             outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");            
627             needcomma=true;
628         }
629
630         arraytable=new TypeDescriptor[state.numArrays()];
631
632         Iterator arrayit=state.getArrayIterator();
633         while(arrayit.hasNext()) {
634             TypeDescriptor td=(TypeDescriptor)arrayit.next();
635             int id=state.getArrayNumber(td);
636             arraytable[id]=td;
637         }
638         
639         for(int i=0;i<state.numArrays();i++) {
640             if (needcomma)
641                 outclassdefs.print(", ");
642             TypeDescriptor tdelement=arraytable[i].dereference();
643             if (tdelement.isArray()||tdelement.isClass())
644                 outclassdefs.print("sizeof(void *)");
645             else
646                 outclassdefs.print("sizeof("+tdelement.getSafeSymbol()+")");
647             needcomma=true;
648         }
649
650         outclassdefs.println("};");
651     }
652
653     /** Constructs params and temp objects for each method or task.
654      * These objects tell the compiler which temps need to be
655      * allocated.  */
656
657     private void generateTempStructs(FlatMethod fm, LocalityBinding lb) {
658         MethodDescriptor md=fm.getMethod();
659         TaskDescriptor task=fm.getTask();
660         Set<TempDescriptor> saveset=state.DSM?locality.getTempSet(lb):null;
661         ParamsObject objectparams=md!=null?new ParamsObject(md,tag++):new ParamsObject(task, tag++);
662
663         if (md!=null)
664             paramstable.put(md, objectparams);
665         else
666             paramstable.put(task, objectparams);
667
668         for(int i=0;i<fm.numParameters();i++) {
669             TempDescriptor temp=fm.getParameter(i);
670             TypeDescriptor type=temp.getType();
671             if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
672                 objectparams.addPtr(temp);
673             else
674                 objectparams.addPrim(temp);
675             if(state.DSM&&saveset.contains(temp)) {
676                 backuptable.put(temp, temp.createNew());
677             }
678         }
679
680         for(int i=0;i<fm.numTags();i++) {
681             TempDescriptor temp=fm.getTag(i);
682             if (GENERATEPRECISEGC)
683                 objectparams.addPtr(temp);
684             else
685                 objectparams.addPrim(temp);
686         }
687
688         TempObject objecttemps=md!=null?new TempObject(objectparams,md,tag++):new TempObject(objectparams, task, tag++);
689         if (md!=null)
690             tempstable.put(md, objecttemps);
691         else
692             tempstable.put(task, objecttemps);
693
694         for(Iterator nodeit=fm.getNodeSet().iterator();nodeit.hasNext();) {
695             FlatNode fn=(FlatNode)nodeit.next();
696             TempDescriptor[] writes=fn.writesTemps();
697             for(int i=0;i<writes.length;i++) {
698                 TempDescriptor temp=writes[i];
699                 TypeDescriptor type=temp.getType();
700                 if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
701                     objecttemps.addPtr(temp);
702                 else
703                     objecttemps.addPrim(temp);
704                 if(state.DSM&&saveset.contains(temp)&&
705                    !backuptable.containsKey(temp))
706                     backuptable.put(temp, temp.createNew());
707             }
708         }
709
710         /* Create backup temps */
711         if (state.DSM)
712             for(Iterator<TempDescriptor> tmpit=backuptable.values().iterator();tmpit.hasNext();) {
713                 TempDescriptor tmp=tmpit.next();
714                 TypeDescriptor type=tmp.getType();
715                 if ((type.isPtr()||type.isArray())&&GENERATEPRECISEGC)
716                     objecttemps.addPtr(tmp);
717                 else
718                     objecttemps.addPrim(tmp);
719             }
720     }
721
722     /** This method outputs the following information about classes
723      * and arrays:
724      * (1) For classes, what are the locations of pointers.
725      * (2) For arrays, does the array contain pointers or primitives.
726      * (3) For classes, does the class contain flags.
727      */
728
729     private void generateLayoutStructs(PrintWriter output) {
730         Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
731         while(it.hasNext()) {
732             ClassDescriptor cn=(ClassDescriptor)it.next();
733             output.println("unsigned int "+cn.getSafeSymbol()+"_pointers[]={");
734             Iterator allit=cn.getFieldTable().getAllDescriptorsIterator();
735             int count=0;
736             while(allit.hasNext()) {
737                 FieldDescriptor fd=(FieldDescriptor)allit.next();
738                 TypeDescriptor type=fd.getType();
739                 if (type.isPtr()||type.isArray())
740                     count++;
741             }
742             output.print(count);
743             allit=cn.getFieldTable().getAllDescriptorsIterator();
744             while(allit.hasNext()) {
745                 FieldDescriptor fd=(FieldDescriptor)allit.next();
746                 TypeDescriptor type=fd.getType();
747                 if (type.isPtr()||type.isArray()) {
748                     output.println(",");
749                     output.print("((unsigned int)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))");
750                 }
751             }
752             output.println("};");
753         }
754         output.println("unsigned int * pointerarray[]={");
755         boolean needcomma=false;
756         for(int i=0;i<state.numClasses();i++) {
757             ClassDescriptor cn=cdarray[i];
758             if (needcomma)
759                 output.println(",");
760             needcomma=true;
761             output.print(cn.getSafeSymbol()+"_pointers");
762         }
763
764         for(int i=0;i<state.numArrays();i++) {
765             if (needcomma)
766                 output.println(", ");
767             TypeDescriptor tdelement=arraytable[i].dereference();
768             if (tdelement.isArray()||tdelement.isClass())
769                 output.print("((int *)1)");
770             else
771                 output.print("0");
772             needcomma=true;
773         }
774         
775         output.println("};");
776         needcomma=false;
777         output.println("int hasflags[]={");
778         for(int i=0;i<state.numClasses();i++) {
779             ClassDescriptor cn=cdarray[i];
780             if (needcomma)
781                 output.println(", ");
782             needcomma=true;
783             if (cn.hasFlags())
784                 output.print("1");
785             else
786                 output.print("0");
787         }
788         output.println("};");
789     }
790
791     /** Print out table to give us supertypes */
792     private void generateSuperTypeTable(PrintWriter output) {
793         output.println("int supertypes[]={");
794         boolean needcomma=false;
795         for(int i=0;i<state.numClasses();i++) {
796             ClassDescriptor cn=cdarray[i];
797             if (needcomma)
798                 output.println(",");
799             needcomma=true;
800             if (cn.getSuperDesc()!=null) {
801                 ClassDescriptor cdsuper=cn.getSuperDesc();
802                 output.print(cdsuper.getId());
803             } else
804                 output.print("-1");
805         }
806         output.println("};");
807     }
808
809     /** Force consistent field ordering between inherited classes. */
810
811     private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) {
812         
813         ClassDescriptor sp=cn.getSuperDesc();
814         if (sp!=null)
815             printClassStruct(sp, classdefout);
816         
817         if (!fieldorder.containsKey(cn)) {
818             Vector fields=new Vector();
819             fieldorder.put(cn,fields);
820             Iterator fieldit=cn.getFields();
821             while(fieldit.hasNext()) {
822                 FieldDescriptor fd=(FieldDescriptor)fieldit.next();
823                 if (sp==null||!sp.getFieldTable().contains(fd.getSymbol()))
824                     fields.add(fd);
825             }
826         }
827         Vector fields=(Vector)fieldorder.get(cn);
828
829         for(int i=0;i<fields.size();i++) {
830             FieldDescriptor fd=(FieldDescriptor)fields.get(i);
831             if (fd.getType().isClass()||fd.getType().isArray())
832                 classdefout.println("  struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
833             else 
834                 classdefout.println("  "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
835         }
836     }
837
838
839     /* Map flags to integers consistently between inherited
840      * classes. */
841
842     private void mapFlags(ClassDescriptor cn) {
843         ClassDescriptor sp=cn.getSuperDesc();
844         if (sp!=null)
845             mapFlags(sp);
846         int max=0;
847         if (!flagorder.containsKey(cn)) {
848             Hashtable flags=new Hashtable();
849             flagorder.put(cn,flags);
850             if (sp!=null) {
851                 Hashtable superflags=(Hashtable)flagorder.get(sp);
852                 Iterator superflagit=superflags.keySet().iterator();
853                 while(superflagit.hasNext()) {
854                     FlagDescriptor fd=(FlagDescriptor)superflagit.next();
855                     Integer number=(Integer)superflags.get(fd);
856                     flags.put(fd, number);
857                     if ((number.intValue()+1)>max)
858                         max=number.intValue()+1;
859                 }
860             }
861             
862             Iterator flagit=cn.getFlags();
863             while(flagit.hasNext()) {
864                 FlagDescriptor fd=(FlagDescriptor)flagit.next();
865                 if (sp==null||!sp.getFlagTable().contains(fd.getSymbol()))
866                     flags.put(fd, new Integer(max++));
867             }
868         }
869     }
870
871
872     /** This function outputs (1) structures that parameters are
873      * passed in (when PRECISE GC is enabled) and (2) function
874      * prototypes for the methods */
875
876     private void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
877         /* Output class structure */
878         classdefout.println("struct "+cn.getSafeSymbol()+" {");
879         classdefout.println("  int type;");
880         if (state.THREAD) {
881             classdefout.println("  pthread_t tid;");
882             classdefout.println("  void * lockentry;");
883             classdefout.println("  int lockcount;");
884         }
885
886         if (state.TASK) {
887             classdefout.println("  int flag;");
888             classdefout.println("  void * flagptr;");
889             if (state.OPTIONAL){
890                 classdefout.println("  int failedstatus;");
891                 classdefout.println("  int hashcode;");
892                 classdefout.println("  int numexitfses;");
893                 classdefout.println("  int * exitfses;");
894                 classdefout.println("  int numotds;");
895                 classdefout.println("  struct optionaltaskdescriptor ** otds;");
896             }
897         }
898         printClassStruct(cn, classdefout);
899         classdefout.println("};\n");
900
901         if (state.DSM) {
902             /* Cycle through LocalityBindings */
903             for(Iterator<LocalityBinding> lbit=locality.getClassBindings(cn).iterator();lbit.hasNext();) {
904                 LocalityBinding lb=lbit.next();
905                 MethodDescriptor md=lb.getMethod();
906                 generateMethod(cn, md, lb, headersout, output);
907             }
908         } else {
909             /* Cycle through methods */
910             for(Iterator methodit=cn.getMethods();methodit.hasNext();) {
911                 /* Classify parameters */
912                 MethodDescriptor md=(MethodDescriptor)methodit.next();
913                 generateMethod(cn, md, null, headersout, output);
914             }
915         }
916     }
917
918     private void generateMethod(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter headersout, PrintWriter output) {
919         FlatMethod fm=state.getMethodFlat(md);
920         generateTempStructs(fm, null);
921         
922         ParamsObject objectparams=(ParamsObject) paramstable.get(md);
923         TempObject objecttemps=(TempObject) tempstable.get(md);
924         
925         /* Output parameter structure */
926         if (GENERATEPRECISEGC) {
927             output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
928             output.println("  int size;");
929             output.println("  void * next;");
930             for(int i=0;i<objectparams.numPointers();i++) {
931                 TempDescriptor temp=objectparams.getPointer(i);
932                 output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
933             }
934             output.println("};\n");
935         }
936         
937         /* Output temp structure */
938         if (GENERATEPRECISEGC) {
939             output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
940             output.println("  int size;");
941             output.println("  void * next;");
942             for(int i=0;i<objecttemps.numPointers();i++) {
943                 TempDescriptor temp=objecttemps.getPointer(i);
944                 if (temp.getType().isNull())
945                     output.println("  void * "+temp.getSafeSymbol()+";");
946                 else
947                     output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
948             }
949             output.println("};\n");
950         }
951         
952         /********* Output method declaration ***********/
953
954         /* First the return type */
955         if (md.getReturnType()!=null) {
956             if (md.getReturnType().isClass()||md.getReturnType().isArray())
957                 headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
958             else
959                 headersout.print(md.getReturnType().getSafeSymbol()+" ");
960         } else 
961             //catch the constructor case
962             headersout.print("void ");
963
964         /* Next the method name */
965         if (state.DSM) {
966             headersout.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
967         } else
968             headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
969         
970         boolean printcomma=false;
971         if (GENERATEPRECISEGC) {
972             headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
973             printcomma=true;
974         }
975         
976         if (state.DSM&&lb.isAtomic()) {
977             if (printcomma)
978                 headersout.print(", ");
979             headersout.print("transrecord_t * trans");
980             printcomma=true;
981         }
982
983         /*  Output parameter list*/
984         for(int i=0;i<objectparams.numPrimitives();i++) {
985             TempDescriptor temp=objectparams.getPrimitive(i);
986             if (printcomma)
987                 headersout.print(", ");
988             printcomma=true;
989             if (temp.getType().isClass()||temp.getType().isArray())
990                 headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
991             else
992                 headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
993         }
994         headersout.println(");\n");
995     }
996
997
998     /** This function outputs (1) structures that parameters are
999      * passed in (when PRECISE GC is enabled) and (2) function
1000      * prototypes for the tasks */
1001
1002     private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
1003         /* Cycle through tasks */
1004         Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
1005
1006         while(taskit.hasNext()) {
1007             /* Classify parameters */
1008             TaskDescriptor task=(TaskDescriptor)taskit.next();
1009             FlatMethod fm=state.getMethodFlat(task);
1010             generateTempStructs(fm, null);
1011
1012             ParamsObject objectparams=(ParamsObject) paramstable.get(task);
1013             TempObject objecttemps=(TempObject) tempstable.get(task);
1014
1015             /* Output parameter structure */
1016             if (GENERATEPRECISEGC) {
1017                 output.println("struct "+task.getSafeSymbol()+"_params {");
1018
1019                 output.println("  int size;");
1020                 output.println("  void * next;");
1021                 for(int i=0;i<objectparams.numPointers();i++) {
1022                     TempDescriptor temp=objectparams.getPointer(i);
1023                     output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1024                 }
1025
1026                 output.println("};\n");
1027                 if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
1028                     maxtaskparams=objectparams.numPointers()+fm.numTags();
1029                 }
1030             }
1031
1032             /* Output temp structure */
1033             if (GENERATEPRECISEGC) {
1034                 output.println("struct "+task.getSafeSymbol()+"_locals {");
1035                 output.println("  int size;");
1036                 output.println("  void * next;");
1037                 for(int i=0;i<objecttemps.numPointers();i++) {
1038                     TempDescriptor temp=objecttemps.getPointer(i);
1039                     if (temp.getType().isNull())
1040                         output.println("  void * "+temp.getSafeSymbol()+";");
1041                     else if(temp.getType().isTag())
1042                         output.println("  struct "+
1043                                        (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1044                     else
1045                         output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1046                 }
1047                 output.println("};\n");
1048             }
1049             
1050             /* Output task declaration */
1051             headersout.print("void " + task.getSafeSymbol()+"(");
1052             
1053             boolean printcomma=false;
1054             if (GENERATEPRECISEGC) {
1055                 headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1056             } else
1057                 headersout.print("void * parameterarray[]");
1058             headersout.println(");\n");
1059         }
1060     }
1061
1062     /** Generate code for FlatMethod fm. */
1063
1064     private void generateFlatMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
1065         MethodDescriptor md=fm.getMethod();
1066         TaskDescriptor task=fm.getTask();
1067
1068         ClassDescriptor cn=md!=null?md.getClassDesc():null;
1069
1070         ParamsObject objectparams=(ParamsObject)paramstable.get(md!=null?md:task);
1071         generateHeader(fm, lb, md!=null?md:task,output);
1072         TempObject objecttemp=(TempObject) tempstable.get(md!=null?md:task);
1073         if (state.DSM&&lb.getHasAtomic()) {
1074             output.println("transrecord_t * trans;");
1075         }
1076
1077         if (GENERATEPRECISEGC) {
1078             if (md!=null)
1079                 output.print("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1080             else
1081                 output.print("   struct "+task.getSafeSymbol()+"_locals "+localsprefix+"={");
1082
1083             output.print(objecttemp.numPointers()+",");
1084             output.print(paramsprefix);
1085             for(int j=0;j<objecttemp.numPointers();j++)
1086                 output.print(", NULL");
1087             output.println("};");
1088         }
1089
1090         for(int i=0;i<objecttemp.numPrimitives();i++) {
1091             TempDescriptor td=objecttemp.getPrimitive(i);
1092             TypeDescriptor type=td.getType();
1093             if (type.isNull())
1094                 output.println("   void * "+td.getSafeSymbol()+";");
1095             else if (type.isClass()||type.isArray())
1096                 output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
1097             else
1098                 output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
1099         }
1100
1101         /* Assign labels to FlatNode's if necessary.*/
1102
1103         Hashtable<FlatNode, Integer> nodetolabel=assignLabels(fm);
1104
1105         /* Check to see if we need to do a GC if this is a
1106          * multi-threaded program...*/
1107
1108         if (state.THREAD&&GENERATEPRECISEGC) {
1109             output.println("checkcollect(&"+localsprefix+");");
1110         }
1111         
1112         /* Do the actual code generation */
1113         FlatNode current_node=null;
1114         HashSet tovisit=new HashSet();
1115         HashSet visited=new HashSet();
1116         tovisit.add(fm.getNext(0));
1117         while(current_node!=null||!tovisit.isEmpty()) {
1118             if (current_node==null) {
1119                 current_node=(FlatNode)tovisit.iterator().next();
1120                 tovisit.remove(current_node);
1121             }
1122             visited.add(current_node);
1123             if (nodetolabel.containsKey(current_node))
1124                 output.println("L"+nodetolabel.get(current_node)+":");
1125             if (state.INSTRUCTIONFAILURE) {
1126                 if (state.THREAD) {
1127                     output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
1128                 }
1129                 else
1130                     output.println("if ((--instructioncount)==0) injectinstructionfailure();");
1131             }
1132             if (current_node.numNext()==0) {
1133                 output.print("   ");
1134                 generateFlatNode(fm, lb, current_node, output);
1135                 if (current_node.kind()!=FKind.FlatReturnNode) {
1136                     output.println("   return;");
1137                 }
1138                 current_node=null;
1139             } else if(current_node.numNext()==1) {
1140                 output.print("   ");
1141                 generateFlatNode(fm, lb, current_node, output);
1142                 FlatNode nextnode=current_node.getNext(0);
1143                 if (visited.contains(nextnode)) {
1144                     output.println("goto L"+nodetolabel.get(nextnode)+";");
1145                     current_node=null;
1146                 } else
1147                     current_node=nextnode;
1148             } else if (current_node.numNext()==2) {
1149                 /* Branch */
1150                 output.print("   ");
1151                 generateFlatCondBranch(fm, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
1152                 if (!visited.contains(current_node.getNext(1)))
1153                     tovisit.add(current_node.getNext(1));
1154                 if (visited.contains(current_node.getNext(0))) {
1155                     output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
1156                     current_node=null;
1157                 } else
1158                     current_node=current_node.getNext(0);
1159             } else throw new Error();
1160         }
1161
1162         output.println("}\n\n");
1163     }
1164
1165     /** This method assigns labels to FlatNodes */
1166
1167     private Hashtable<FlatNode, Integer> assignLabels(FlatMethod fm) {
1168         HashSet tovisit=new HashSet();
1169         HashSet visited=new HashSet();
1170         int labelindex=0;
1171         Hashtable<FlatNode, Integer> nodetolabel=new Hashtable<FlatNode, Integer>();
1172         tovisit.add(fm.getNext(0));
1173
1174         /*Assign labels first.  A node needs a label if the previous
1175          * node has two exits or this node is a join point. */
1176
1177         while(!tovisit.isEmpty()) {
1178             FlatNode fn=(FlatNode)tovisit.iterator().next();
1179             tovisit.remove(fn);
1180             visited.add(fn);
1181             for(int i=0;i<fn.numNext();i++) {
1182                 FlatNode nn=fn.getNext(i);
1183                 if(i>0) {
1184                     //1) Edge >1 of node
1185                     nodetolabel.put(nn,new Integer(labelindex++));
1186                 }
1187                 if (!visited.contains(nn)&&!tovisit.contains(nn)) {
1188                     tovisit.add(nn);
1189                 } else {
1190                     //2) Join point
1191                     nodetolabel.put(nn,new Integer(labelindex++));
1192                 }
1193             }
1194         }
1195         return nodetolabel;
1196     }
1197
1198
1199     /** Generate text string that corresponds to the TempDescriptor td. */
1200     private String generateTemp(FlatMethod fm, TempDescriptor td) {
1201         MethodDescriptor md=fm.getMethod();
1202         TaskDescriptor task=fm.getTask();
1203         TempObject objecttemps=(TempObject) tempstable.get(md!=null?md:task);
1204
1205         if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1206             return td.getSafeSymbol();
1207         }
1208
1209         if (objecttemps.isLocalPtr(td)) {
1210             return localsprefix+"."+td.getSafeSymbol();
1211         }
1212
1213         if (objecttemps.isParamPtr(td)) {
1214             return paramsprefix+"->"+td.getSafeSymbol();
1215         }
1216         throw new Error();
1217     }
1218
1219     private void generateFlatNode(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output) {
1220         switch(fn.kind()) {
1221         case FKind.FlatAtomicEnterNode:
1222             generateFlatAtomicEnterNode(fm, lb, (FlatAtomicEnterNode) fn, output);
1223             return;
1224         case FKind.FlatAtomicExitNode:
1225             generateFlatAtomicExitNode(fm, lb, (FlatAtomicExitNode) fn, output);
1226             return;
1227         case FKind.FlatTagDeclaration:
1228             generateFlatTagDeclaration(fm, (FlatTagDeclaration) fn,output);
1229             return;
1230         case FKind.FlatCall:
1231             generateFlatCall(fm, (FlatCall) fn,output);
1232             return;
1233         case FKind.FlatFieldNode:
1234             generateFlatFieldNode(fm, lb, (FlatFieldNode) fn,output);
1235             return;
1236         case FKind.FlatElementNode:
1237             generateFlatElementNode(fm, (FlatElementNode) fn,output);
1238             return;
1239         case FKind.FlatSetElementNode:
1240             generateFlatSetElementNode(fm, (FlatSetElementNode) fn,output);
1241             return;
1242         case FKind.FlatSetFieldNode:
1243             generateFlatSetFieldNode(fm, lb, (FlatSetFieldNode) fn,output);
1244             return;
1245         case FKind.FlatNew:
1246             generateFlatNew(fm, (FlatNew) fn,output);
1247             return;
1248         case FKind.FlatOpNode:
1249             generateFlatOpNode(fm, (FlatOpNode) fn,output);
1250             return;
1251         case FKind.FlatCastNode:
1252             generateFlatCastNode(fm, (FlatCastNode) fn,output);
1253             return;
1254         case FKind.FlatLiteralNode:
1255             generateFlatLiteralNode(fm, (FlatLiteralNode) fn,output);
1256             return;
1257         case FKind.FlatReturnNode:
1258             generateFlatReturnNode(fm, (FlatReturnNode) fn,output);
1259             return;
1260         case FKind.FlatNop:
1261             output.println("/* nop */");
1262             return;
1263         case FKind.FlatBackEdge:
1264             if (state.THREAD&&GENERATEPRECISEGC) {
1265                 output.println("checkcollect(&"+localsprefix+");");
1266             } else
1267                 output.println("/* nop */");
1268             return;
1269         case FKind.FlatCheckNode:
1270             generateFlatCheckNode(fm, (FlatCheckNode) fn, output);
1271             return;
1272         case FKind.FlatFlagActionNode:
1273             generateFlatFlagActionNode(fm, (FlatFlagActionNode) fn, output);
1274             return;
1275         }
1276         throw new Error();
1277
1278     }
1279     
1280     public void generateFlatAtomicEnterNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicEnterNode faen, PrintWriter output) {
1281         /* Check to see if we need to generate code for this atomic */
1282         if (locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
1283             return;
1284         /* Backup the temps. */
1285         for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) {
1286             TempDescriptor tmp=tmpit.next();
1287             output.println(generateTemp(fm, backuptable.get(tmp))+"="+generateTemp(fm,tmp)+";");
1288         }
1289         output.println("goto transstart"+faen.getIdentifier()+";");
1290
1291         /******* Print code to retry aborted transaction *******/
1292         output.println("transretry"+faen.getIdentifier()+":");
1293
1294         /* Restore temps */
1295         for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) {
1296             TempDescriptor tmp=tmpit.next();
1297             output.println(generateTemp(fm, tmp)+"="+generateTemp(fm,backuptable.get(tmp))+";");
1298         }
1299
1300         /* Need to revert local object store */
1301
1302         /******* Tell the runtime to start the transaction *******/
1303         
1304         output.println("transstart"+faen.getIdentifier()+":");
1305         output.println("trans=transStart();");
1306     }
1307
1308     public void generateFlatAtomicExitNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicExitNode faen, PrintWriter output) {
1309         /* Check to see if we need to generate code for this atomic */
1310         if (locality.getAtomic(lb).get(faen).intValue()>0)
1311             return;
1312         output.println("if (transCommit(trans))");
1313         /* Transaction aborts if it returns true */
1314         output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
1315         /* Need to commit local object store */
1316         //TODO
1317     }
1318
1319     private void generateFlatCheckNode(FlatMethod fm,  FlatCheckNode fcn, PrintWriter output) {
1320         if (state.CONSCHECK) {
1321             String specname=fcn.getSpec();
1322             String varname="repairstate___";
1323             output.println("{");
1324             output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
1325
1326             TempDescriptor[] temps=fcn.getTemps();
1327             String[] vars=fcn.getVars();
1328             for(int i=0;i<temps.length;i++) {
1329                 output.println(varname+"->"+vars[i]+"=(unsigned int)"+generateTemp(fm, temps[i])+";");
1330             }
1331
1332             output.println("if (doanalysis"+specname+"("+varname+")) {");
1333             output.println("free"+specname+"_state("+varname+");");
1334             output.println("} else {");
1335             output.println("/* Bad invariant */");
1336             output.println("free"+specname+"_state("+varname+");");
1337             output.println("abort_task();");
1338             output.println("}");
1339             output.println("}");
1340         }
1341     }
1342
1343     private void generateFlatCall(FlatMethod fm, FlatCall fc, PrintWriter output) {
1344         MethodDescriptor md=fc.getMethod();
1345         ParamsObject objectparams=(ParamsObject) paramstable.get(md);
1346         ClassDescriptor cn=md.getClassDesc();
1347         output.println("{");
1348         if (GENERATEPRECISEGC) {
1349             output.print("       struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
1350             
1351             output.print(objectparams.numPointers());
1352             //      output.print(objectparams.getUID());
1353             output.print(", & "+localsprefix);
1354             if (fc.getThis()!=null) {
1355                 output.print(", ");
1356                 output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis()));
1357             }
1358             for(int i=0;i<fc.numArgs();i++) {
1359                 Descriptor var=md.getParameter(i);
1360                 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1361                 if (objectparams.isParamPtr(paramtemp)) {
1362                     TempDescriptor targ=fc.getArg(i);
1363                     output.print(", ");
1364                     TypeDescriptor td=md.getParamType(i);
1365                     if (td.isTag())
1366                         output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()  +" *)"+generateTemp(fm, targ));
1367                     else
1368                         output.print("(struct "+md.getParamType(i).getSafeSymbol()  +" *)"+generateTemp(fm, targ));
1369                 }
1370             }
1371             output.println("};");
1372         }
1373         output.print("       ");
1374
1375
1376         if (fc.getReturnTemp()!=null)
1377             output.print(generateTemp(fm,fc.getReturnTemp())+"=");
1378
1379         /* Do we need to do virtual dispatch? */
1380         if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
1381             output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
1382         } else {
1383             output.print("((");
1384             if (md.getReturnType().isClass()||md.getReturnType().isArray())
1385                 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1386             else
1387                 output.print(md.getReturnType().getSafeSymbol()+" ");
1388             output.print("(*)(");
1389
1390             boolean printcomma=false;
1391             if (GENERATEPRECISEGC) {
1392                 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
1393                 printcomma=true;
1394             }
1395
1396             for(int i=0;i<objectparams.numPrimitives();i++) {
1397                 TempDescriptor temp=objectparams.getPrimitive(i);
1398                 if (printcomma)
1399                     output.print(", ");
1400                 printcomma=true;
1401                 if (temp.getType().isClass()||temp.getType().isArray())
1402                     output.print("struct " + temp.getType().getSafeSymbol()+" * ");
1403                 else
1404                     output.print(temp.getType().getSafeSymbol());
1405             }
1406
1407             output.print("))virtualtable["+generateTemp(fm,fc.getThis())+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
1408         }
1409
1410         output.print("(");
1411         boolean needcomma=false;
1412         if (GENERATEPRECISEGC) {
1413             output.print("&__parameterlist__");
1414             needcomma=true;
1415         } else {
1416             if (fc.getThis()!=null) {
1417                 TypeDescriptor ptd=md.getThis().getType();
1418                 if (ptd.isClass()&&!ptd.isArray())
1419                     output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1420                 output.print(generateTemp(fm,fc.getThis()));
1421                 needcomma=true;
1422             }
1423         }
1424         for(int i=0;i<fc.numArgs();i++) {
1425             Descriptor var=md.getParameter(i);
1426             TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1427             if (objectparams.isParamPrim(paramtemp)) {
1428                 TempDescriptor targ=fc.getArg(i);
1429                 if (needcomma)
1430                     output.print(", ");
1431
1432                 TypeDescriptor ptd=md.getParamType(i);
1433                 if (ptd.isClass()&&!ptd.isArray())
1434                     output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1435                 output.print(generateTemp(fm, targ));
1436                 needcomma=true;
1437             }
1438         }
1439         output.println(");");
1440         output.println("   }");
1441     }
1442
1443     private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
1444         Set subclasses=typeutil.getSubClasses(thiscd);
1445         if (subclasses==null)
1446             return true;
1447         for(Iterator classit=subclasses.iterator();classit.hasNext();) {
1448             ClassDescriptor cd=(ClassDescriptor)classit.next();
1449             Set possiblematches=cd.getMethodTable().getSet(md.getSymbol());
1450             for(Iterator matchit=possiblematches.iterator();matchit.hasNext();) {
1451                 MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
1452                 if (md.matches(matchmd))
1453                     return false;
1454             }
1455         }
1456         return true;
1457     }
1458
1459     private void generateFlatFieldNode(FlatMethod fm, LocalityBinding lb, FlatFieldNode ffn, PrintWriter output) {
1460         if (state.DSM) {
1461             Integer status=locality.getNodeTempInfo(lb).get(ffn).get(ffn.getSrc());
1462             if (status==LocalityAnalysis.GLOBAL) {
1463                 String field=ffn.getField().getSafeSymbol();
1464                 String src="((struct "+ffn.getSrc().getType().getSafeSymbol()+" *)((unsigned int)"+generateTemp(fm, ffn.getSrc())+"+sizeof(objheader_t)))";
1465                 String dst=generateTemp(fm, ffn.getDst());
1466                     
1467                 if (ffn.getField().getType().isPtr()||
1468                     ffn.getField().getType().isArray()) {
1469
1470                     //TODO: Uncomment this when we have runtime support
1471                     //if (ffn.getSrc()==ffn.getDst()) {
1472                     //output.println("{");
1473                     //output.println("void * temp="+src+";");
1474                     //output.println("if (temp&0x1) {");
1475                     //output.println("temp=transRead(trans, temp);");
1476                     //output.println(src+"->"+field+"="+temp+";");
1477                     //output.println("}");
1478                     //output.println(dst+"=temp;");
1479                     //output.println("}");
1480                     //} else {
1481                     output.println(dst+"="+ src +"->"+field+ ";");
1482                     //output.println("if ("+dst+"&0x1) {");
1483                     output.println(dst+"=transRead(trans,"+dst+");");
1484                     //output.println(src+"->"+field+"="+src+"->"+field+";");
1485                     //output.println("}");
1486                     //}
1487                 } else {
1488                     output.println(dst+"="+ src+"->"+field+";");
1489                 }
1490             } else if (status==LocalityAnalysis.LOCAL) {
1491                 output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
1492             } else if (status==LocalityAnalysis.EITHER) {
1493                 //Code is reading from a null pointer
1494                 output.println("if ("+generateTemp(fm, ffn.getSrc())+") {");
1495                 output.println("printf(\"BIG ERROR\n\");exit(-1);}");
1496                 //This should throw a suitable null pointer error
1497                 output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
1498             } else
1499                 throw new Error("Read from non-global/non-local in:"+lb.getExplanation());
1500         } else
1501             output.println(generateTemp(fm, ffn.getDst())+"="+ generateTemp(fm,ffn.getSrc())+"->"+ ffn.getField().getSafeSymbol()+";");
1502     }
1503
1504     private void generateFlatSetFieldNode(FlatMethod fm, LocalityBinding lb, FlatSetFieldNode fsfn, PrintWriter output) {
1505         if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
1506             throw new Error("Can't set array length");
1507         if (state.DSM) {
1508             Integer statussrc=locality.getNodeTempInfo(lb).get(fsfn).get(fsfn.getDst());
1509             Integer statusdst=locality.getNodeTempInfo(lb).get(fsfn).get(fsfn.getDst());
1510             boolean srcglobal=statusdst==LocalityAnalysis.GLOBAL;
1511
1512             String src=generateTemp(fm,fsfn.getSrc());
1513             String dst=generateTemp(fm,fsfn.getDst());
1514             if (srcglobal) {
1515                 output.println("{");
1516                 output.println("int srcoid="+src+"->"+oidstr+";");
1517             }
1518             if (statusdst.equals(LocalityAnalysis.GLOBAL)) {
1519                 String glbdst="(struct "+fsfn.getDst().getType().getSafeSymbol()+" *)((unsigned int)"+dst+" +sizeof(objheader_t)))";
1520                 //mark it dirty
1521                 output.println("((objheader_t *)"+dst+")->status|=DIRTY;");
1522                 if (srcglobal)
1523                     output.println(glbdst+"->"+ fsfn.getField().getSafeSymbol()+"=srcoid;");
1524                 else
1525                     output.println(glbdst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");          
1526             } else if (statusdst.equals(LocalityAnalysis.LOCAL)) {
1527                 /** Check if we need to copy */
1528                 output.println("if(!"+dst+"->"+localcopystr+") {");
1529                 /* Link object into list */
1530                 output.println(dst+"->"+nextobjstr+"=trans->localtrans;");
1531                 output.println("trans->localtrans="+dst+";");
1532                 output.println("OBJECT_COPY("+dst+");");
1533                 output.println("}");
1534                 if (srcglobal)
1535                     output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=srcoid;");
1536                 else
1537                     output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
1538             } else if (statusdst.equals(LocalityAnalysis.EITHER)) {
1539                 //writing to a null...bad
1540                 output.println("if ("+dst+") {");
1541                 output.println("printf(\"BIG ERROR 2\n\");exit(-1);}");
1542                 if (srcglobal)
1543                     output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=srcoid;");
1544                 else
1545                     output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
1546             }
1547             if (srcglobal) {
1548                 output.println("}");
1549             }
1550         } else {
1551             output.println(generateTemp(fm, fsfn.getDst())+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc())+";");
1552         }
1553     }
1554
1555     private void generateFlatElementNode(FlatMethod fm, FlatElementNode fen, PrintWriter output) {
1556         TypeDescriptor elementtype=fen.getSrc().getType().dereference();
1557         String type="";
1558
1559         if (elementtype.isArray()||elementtype.isClass())
1560             type="void *";
1561         else 
1562             type=elementtype.getSafeSymbol()+" ";
1563
1564         if (fen.needsBoundsCheck()) {
1565             output.println("if ("+generateTemp(fm, fen.getIndex())+"< 0 || "+generateTemp(fm, fen.getIndex())+" >= "+generateTemp(fm,fen.getSrc()) + "->___length___)");
1566             output.println("failedboundschk();");
1567         }
1568
1569         output.println(generateTemp(fm, fen.getDst())+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc())+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex())+"];");
1570     }
1571
1572     private void generateFlatSetElementNode(FlatMethod fm, FlatSetElementNode fsen, PrintWriter output) {
1573         //TODO: need dynamic check to make sure this assignment is actually legal
1574         //Because Object[] could actually be something more specific...ie. Integer[]
1575
1576         TypeDescriptor elementtype=fsen.getDst().getType().dereference();
1577         String type="";
1578
1579         if (elementtype.isArray()||elementtype.isClass())
1580             type="void *";
1581         else 
1582             type=elementtype.getSafeSymbol()+" ";
1583
1584         if (fsen.needsBoundsCheck()) {
1585             output.println("if ("+generateTemp(fm, fsen.getIndex())+"< 0 || "+generateTemp(fm, fsen.getIndex())+" >= "+generateTemp(fm,fsen.getDst()) + "->___length___)");
1586             output.println("failedboundschk();");
1587         }
1588
1589         output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst())+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex())+"]="+generateTemp(fm,fsen.getSrc())+";");
1590     }
1591
1592     private void generateFlatNew(FlatMethod fm, FlatNew fn, PrintWriter output) {
1593         if (fn.getType().isArray()) {
1594             int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
1595             if (GENERATEPRECISEGC) {
1596                 output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize())+");");
1597             } else {
1598                 output.println(generateTemp(fm,fn.getDst())+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize())+");");
1599             }
1600         } else {
1601             if (GENERATEPRECISEGC) {
1602                 output.println(generateTemp(fm,fn.getDst())+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
1603             } else {
1604                 output.println(generateTemp(fm,fn.getDst())+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
1605             }
1606         }
1607     }
1608
1609     private void generateFlatTagDeclaration(FlatMethod fm, FlatTagDeclaration fn, PrintWriter output) {
1610         if (GENERATEPRECISEGC) {
1611             output.println(generateTemp(fm,fn.getDst())+"=allocate_tag(&"+localsprefix+", "+state.getTagId(fn.getType())+");");
1612         } else {
1613             output.println(generateTemp(fm,fn.getDst())+"=allocate_tag("+state.getTagId(fn.getType())+");");
1614         }
1615     }
1616
1617     private void generateFlatOpNode(FlatMethod fm, FlatOpNode fon, PrintWriter output) {
1618         if (fon.getRight()!=null)
1619             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+fon.getOp().toString()+generateTemp(fm,fon.getRight())+";");
1620         else if (fon.getOp().getOp()==Operation.ASSIGN)
1621             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
1622         else if (fon.getOp().getOp()==Operation.UNARYPLUS)
1623             output.println(generateTemp(fm, fon.getDest())+" = "+generateTemp(fm, fon.getLeft())+";");
1624         else if (fon.getOp().getOp()==Operation.UNARYMINUS)
1625             output.println(generateTemp(fm, fon.getDest())+" = -"+generateTemp(fm, fon.getLeft())+";");
1626         else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
1627             output.println(generateTemp(fm, fon.getDest())+" = !"+generateTemp(fm, fon.getLeft())+";");
1628         else
1629             output.println(generateTemp(fm, fon.getDest())+fon.getOp().toString()+generateTemp(fm, fon.getLeft())+";");
1630     }
1631
1632     private void generateFlatCastNode(FlatMethod fm, FlatCastNode fcn, PrintWriter output) {
1633         /* TODO: Do type check here */
1634         if (fcn.getType().isArray()) {
1635             throw new Error();
1636         } else if (fcn.getType().isClass())
1637             output.println(generateTemp(fm,fcn.getDst())+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc())+";");
1638         else
1639             output.println(generateTemp(fm,fcn.getDst())+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc())+";");
1640     }
1641
1642     private void generateFlatLiteralNode(FlatMethod fm, FlatLiteralNode fln, PrintWriter output) {
1643         if (fln.getValue()==null)
1644             output.println(generateTemp(fm, fln.getDst())+"=0;");
1645         else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
1646             if (GENERATEPRECISEGC) {
1647                 output.println(generateTemp(fm, fln.getDst())+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1648             } else {
1649                 output.println(generateTemp(fm, fln.getDst())+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1650             }
1651         } else if (fln.getType().isBoolean()) {
1652             if (((Boolean)fln.getValue()).booleanValue())
1653                 output.println(generateTemp(fm, fln.getDst())+"=1;");
1654             else
1655                 output.println(generateTemp(fm, fln.getDst())+"=0;");
1656         } else if (fln.getType().isChar()) {
1657             String st=FlatLiteralNode.escapeString(fln.getValue().toString());
1658             output.println(generateTemp(fm, fln.getDst())+"='"+st+"';");
1659         } else
1660             output.println(generateTemp(fm, fln.getDst())+"="+fln.getValue()+";");
1661     }
1662
1663     private void generateFlatReturnNode(FlatMethod fm, FlatReturnNode frn, PrintWriter output) {
1664         if (frn.getReturnTemp()!=null)
1665             output.println("return "+generateTemp(fm, frn.getReturnTemp())+";");
1666         else
1667             output.println("return;");
1668     }
1669
1670     private void generateFlatCondBranch(FlatMethod fm, FlatCondBranch fcb, String label, PrintWriter output) {
1671         output.println("if (!"+generateTemp(fm, fcb.getTest())+") goto "+label+";");
1672     }
1673
1674     /** This method generates header information for the method or
1675      * task referenced by the Descriptor des. */
1676
1677     private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
1678         /* Print header */
1679         ParamsObject objectparams=(ParamsObject)paramstable.get(des);
1680         MethodDescriptor md=null;
1681         TaskDescriptor task=null;
1682         if (des instanceof MethodDescriptor)
1683             md=(MethodDescriptor) des;
1684         else
1685             task=(TaskDescriptor) des;
1686
1687         ClassDescriptor cn=md!=null?md.getClassDesc():null;
1688         
1689         if (md!=null&&md.getReturnType()!=null) {
1690             if (md.getReturnType().isClass()||md.getReturnType().isArray())
1691                 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1692             else
1693                 output.print(md.getReturnType().getSafeSymbol()+" ");
1694         } else 
1695             //catch the constructor case
1696             output.print("void ");
1697         if (md!=null) {
1698             if (state.DSM) {
1699                 output.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1700             } else
1701                 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1702         } else
1703             output.print(task.getSafeSymbol()+"(");
1704         
1705         boolean printcomma=false;
1706         if (GENERATEPRECISEGC) {
1707             if (md!=null)
1708                 output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1709             else
1710                 output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1711             printcomma=true;
1712         }
1713
1714         if (state.DSM&&lb.isAtomic()) {
1715             if (printcomma)
1716                 output.print(", ");
1717             output.print("transrecord_t * trans");
1718             printcomma=true;
1719         }
1720
1721         if (md!=null) {
1722             /* Method */
1723             for(int i=0;i<objectparams.numPrimitives();i++) {
1724                 TempDescriptor temp=objectparams.getPrimitive(i);
1725                 if (printcomma)
1726                     output.print(", ");
1727                 printcomma=true;
1728                 if (temp.getType().isClass()||temp.getType().isArray())
1729                     output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1730                 else
1731                     output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1732             }
1733             output.println(") {");
1734         } else if (!GENERATEPRECISEGC) {
1735             /* Imprecise Task */
1736             output.println("void * parameterarray[]) {");
1737             /* Unpack variables */
1738             for(int i=0;i<objectparams.numPrimitives();i++) {
1739                 TempDescriptor temp=objectparams.getPrimitive(i);
1740                 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
1741             }
1742             for(int i=0;i<fm.numTags();i++) {
1743                 TempDescriptor temp=fm.getTag(i);
1744                 int offset=i+objectparams.numPrimitives();
1745                 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
1746             }
1747
1748             if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
1749                 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
1750         } else output.println(") {");
1751     }
1752     
1753     public void generateFlatFlagActionNode(FlatMethod fm, FlatFlagActionNode ffan, PrintWriter output) {
1754         output.println("/* FlatFlagActionNode */");
1755
1756
1757         /* Process tag changes */
1758         Relation tagsettable=new Relation();
1759         Relation tagcleartable=new Relation();
1760
1761         Iterator tagsit=ffan.getTempTagPairs(); 
1762         while (tagsit.hasNext()) {
1763             TempTagPair ttp=(TempTagPair) tagsit.next();
1764             TempDescriptor objtmp=ttp.getTemp();
1765             TagDescriptor tag=ttp.getTag();
1766             TempDescriptor tagtmp=ttp.getTagTemp();
1767             boolean tagstatus=ffan.getTagChange(ttp);
1768             if (tagstatus) {
1769                 tagsettable.put(objtmp, tagtmp);
1770             } else {
1771                 tagcleartable.put(objtmp, tagtmp);
1772             }
1773         }
1774
1775
1776         Hashtable flagandtable=new Hashtable();
1777         Hashtable flagortable=new Hashtable();
1778
1779         /* Process flag changes */
1780         Iterator flagsit=ffan.getTempFlagPairs();
1781         while(flagsit.hasNext()) {
1782             TempFlagPair tfp=(TempFlagPair)flagsit.next();
1783             TempDescriptor temp=tfp.getTemp();
1784             Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
1785             FlagDescriptor flag=tfp.getFlag();
1786             if (flag==null) {
1787                 //Newly allocate objects that don't set any flags case
1788                 if (flagortable.containsKey(temp)) {
1789                     throw new Error();
1790                 }
1791                 int mask=0;
1792                 flagortable.put(temp,new Integer(mask));
1793             } else {
1794                 int flagid=1<<((Integer)flagtable.get(flag)).intValue();
1795                 boolean flagstatus=ffan.getFlagChange(tfp);
1796                 if (flagstatus) {
1797                     int mask=0;
1798                     if (flagortable.containsKey(temp)) {
1799                         mask=((Integer)flagortable.get(temp)).intValue();
1800                     }
1801                     mask|=flagid;
1802                     flagortable.put(temp,new Integer(mask));
1803                 } else {
1804                     int mask=0xFFFFFFFF;
1805                     if (flagandtable.containsKey(temp)) {
1806                         mask=((Integer)flagandtable.get(temp)).intValue();
1807                     }
1808                     mask&=(0xFFFFFFFF^flagid);
1809                     flagandtable.put(temp,new Integer(mask));
1810                 }
1811             }
1812         }
1813
1814
1815         HashSet flagtagset=new HashSet();
1816         flagtagset.addAll(flagortable.keySet());
1817         flagtagset.addAll(flagandtable.keySet());
1818         flagtagset.addAll(tagsettable.keySet());
1819         flagtagset.addAll(tagcleartable.keySet());
1820
1821         Iterator ftit=flagtagset.iterator();
1822         while(ftit.hasNext()) {
1823             TempDescriptor temp=(TempDescriptor)ftit.next();
1824             
1825             
1826             Set tagtmps=tagcleartable.get(temp);
1827             if (tagtmps!=null) {
1828                 Iterator tagit=tagtmps.iterator();
1829                 while(tagit.hasNext()) {
1830                     TempDescriptor tagtmp=(TempDescriptor)tagit.next();
1831                     if (GENERATEPRECISEGC) 
1832                         output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1833                     else
1834                         output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1835                 }
1836             }
1837
1838             tagtmps=tagsettable.get(temp);
1839             if (tagtmps!=null) {
1840                 Iterator tagit=tagtmps.iterator();
1841                 while(tagit.hasNext()) {
1842                     TempDescriptor tagtmp=(TempDescriptor)tagit.next();
1843                     if (GENERATEPRECISEGC)
1844                         output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1845                     else
1846                         output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");");
1847                 }
1848             }
1849
1850             int ormask=0;
1851             int andmask=0xFFFFFFF;
1852             
1853             if (flagortable.containsKey(temp))
1854                 ormask=((Integer)flagortable.get(temp)).intValue();
1855             if (flagandtable.containsKey(temp))
1856                 andmask=((Integer)flagandtable.get(temp)).intValue();
1857             if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
1858                 output.println("flagorandinit("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
1859             } else {
1860                 output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
1861             }
1862         }
1863     }
1864
1865      void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> safeexecution, Hashtable optionaltaskdescriptors) {
1866          
1867          //GENERATE HEADERS
1868          headers.println("#include \"task.h\"\n\n");
1869          headers.println("#ifndef _OPTIONAL_STRUCT_");
1870          headers.println("#define _OPTIONAL_STRUCT_");
1871          
1872          
1873          
1874          
1875          //STRUCT PREDICATEMEMBER
1876          headers.println("struct predicatemember{");
1877          headers.println("int type;");
1878          headers.println("int numdnfterms;");
1879          headers.println("int * flags;");
1880          headers.println("int numtags;");
1881          headers.println("int * tags;\n};\n\n");
1882
1883          /*//STRUCT EXITSTATES
1884          headers.println("struct exitstates{");
1885          headers.println("int numflagstates;");
1886          headers.println("int * flagstatearray;\n};\n\n");*///appeared to be useless
1887
1888          //STRUCT OPTIONALTASKDESCRIPTOR
1889          headers.println("struct optionaltaskdescriptor{");
1890          headers.println("struct taskdescriptor * task;");
1891          headers.println("int numenterflags;");
1892          headers.println("int * enterflags;");
1893          headers.println("int numpredicatemembers;");
1894          headers.println("struct predicatemember ** predicatememberarray;");
1895          //headers.println("int numexitstates;");
1896          //headers.println("int numTotal;");
1897          //headers.println("struct exitstates ** exitstatesarray;\n};\n\n");
1898          headers.println("\n};\n\n");
1899                  
1900          //STRUCT FSANALYSISWRAPPER
1901          headers.println("struct fsanalysiswrapper{");
1902          headers.println("int  flags;");
1903          headers.println("int numtags;");
1904          headers.println("int * tags;");
1905          headers.println("int numoptionaltaskdescriptors;");
1906          headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
1907
1908          //STRUCT CLASSANALYSISWRAPPER
1909          headers.println("struct classanalysiswrapper{");
1910          headers.println("int type;");
1911          headers.println("int numotd;");
1912          headers.println("struct optionaltaskdescriptor ** otdarray;");
1913          headers.println("int numfsanalysiswrappers;");
1914          headers.println("struct fsanalysiswrapper ** fsanalysiswrapperarray;\n};\n\n");
1915          
1916          headers.println("struct classanalysiswrapper * classanalysiswrapperarray[];\n");
1917
1918         
1919
1920          Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
1921          while(taskit.hasNext()) {
1922              TaskDescriptor td=(TaskDescriptor)taskit.next();
1923              headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
1924          }
1925          
1926          
1927          
1928          //GENERATE STRUCTS
1929          output.println("#include \"optionalstruct.h\"\n\n");    
1930          HashSet processedcd = new HashSet();
1931         
1932          int maxotd=0;
1933          Enumeration e = safeexecution.keys();
1934          while (e.hasMoreElements()) {
1935              int numotd=0;
1936              //get the class
1937              ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
1938              Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);//will be used several times
1939              
1940              //////////////////////////DEBUG
1941              System.out.println(cdtemp.getSymbol()+" "+cdtemp.getId());
1942              for(Iterator flags = cdtemp.getFlags(); flags.hasNext();){
1943                  FlagDescriptor flagd = (FlagDescriptor)flags.next();
1944                  int flagid=1<<((Integer)flaginfo.get(flagd)).intValue();
1945                  System.out.println(" Flag "+flagd.getSymbol()+" 0x"+Integer.toHexString(flagid)+" int "+flagid);
1946              }
1947              ///////////////////////////
1948              
1949              //Generate the struct of optionals
1950              if((Hashtable)optionaltaskdescriptors.get(cdtemp)==null) System.out.println("Was in cd :"+cdtemp.getSymbol());
1951              Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
1952              numotd = c_otd.size();
1953              if(maxotd<numotd) maxotd = numotd; 
1954              if( !c_otd.isEmpty() ){
1955                  for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
1956                      OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
1957                      
1958                      //generate the int arrays for the predicate
1959                      Predicate predicate = otd.predicate;
1960                      int predicateindex = 0;
1961                      //iterate through the classes concerned by the predicate
1962                      Collection c_vard = predicate.vardescriptors.values();
1963                      for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();){
1964                          VarDescriptor vard = (VarDescriptor)vard_it.next();
1965                          TypeDescriptor typed = vard.getType();
1966                          
1967                          //generate for flags
1968                          HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
1969                          output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
1970                          int numberterms=0;
1971                          if (fen_hashset!=null){
1972                              for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();){
1973                                  FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
1974                                  if (fen==null) {
1975                                  }    
1976                                  else {
1977                                      
1978                                      DNFFlag dflag=fen.getDNF();
1979                                      numberterms+=dflag.size();
1980                                      
1981                                      Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
1982                                      
1983                                      for(int j=0;j<dflag.size();j++) {
1984                                          if (j!=0)
1985                                              output.println(",");
1986                                          Vector term=dflag.get(j);
1987                                          int andmask=0;
1988                                          int checkmask=0;
1989                                          for(int k=0;k<term.size();k++) {
1990                                              DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
1991                                              FlagDescriptor fd=dfa.getFlag();
1992                                              boolean negated=dfa.getNegated();
1993                                              int flagid=1<<((Integer)flags.get(fd)).intValue();
1994                                              andmask|=flagid;
1995                                              if (!negated)
1996                                                  checkmask|=flagid;
1997                                          }
1998                                          output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
1999                                      }
2000                                  }
2001                              }
2002                          }
2003                          output.println("};\n");
2004                          
2005                          //generate for tags
2006                          TagExpressionList tagel = predicate.tags.get(vard.getSymbol()); 
2007                          output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2008                          //BUG...added next line to fix, test with any task program
2009                          int numtags = 0;
2010                          if (tagel!=null){
2011                              for(int j=0;j<tagel.numTags();j++) {
2012                                  if (j!=0)
2013                                      output.println(",");
2014                                  TempDescriptor tmp=tagel.getTemp(j);
2015                                  //got rid of slot, maybe some improvments to do ???
2016                                  output.println("/*tagid*/"+state.getTagId(tmp.getTag()));
2017                              }
2018                              numtags = tagel.numTags();
2019                          }
2020                          output.println("};");
2021                          
2022                          //store the result into a predicatemember struct
2023                          output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
2024                          output.println("/*type*/"+typed.getClassDesc().getId()+",");
2025                          output.println("/* number of dnf terms */"+numberterms+",");
2026                          output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2027                          output.println("/* number of tag */"+numtags+",");
2028                          output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2029                          output.println("};\n");
2030                          predicateindex++;
2031                      }
2032                      
2033
2034                      //generate an array that stores the entire predicate
2035                      output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2036                      for( int j = 0; j<predicateindex; j++){
2037                          if( j != predicateindex-1)output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2038                          else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
2039                      }
2040                      output.println("};\n");
2041
2042                      //generate the struct for possible exitfses, appeared to be useless
2043                      /*HashSet<HashSet> exitfses = otd.exitfses;
2044                      int exitindex = 0;
2045                      int nbexit = exitfses.size();
2046                      int fsnumber;
2047                      
2048                      //iterate through possible exits
2049                      int nbtotal=0;
2050                      for(Iterator exitfseshash = exitfses.iterator(); exitfseshash.hasNext();){
2051                          HashSet temp_hashset = (HashSet)exitfseshash.next();
2052                          fsnumber = 0 ;
2053                          output.println("int flag_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2054                          //iterate through possible FSes corresponding to the exit
2055                          for(Iterator exfses = temp_hashset.iterator(); exfses.hasNext();){
2056                              FlagState fs = (FlagState)exfses.next();
2057                              fsnumber++;
2058                              nbtotal++;
2059                              int flagid=0;
2060                              for(Iterator flags = fs.getFlags(); flags.hasNext();){
2061                                  FlagDescriptor flagd = (FlagDescriptor)flags.next();
2062                                  int id=1<<((Integer)flaginfo.get(flagd)).intValue();
2063                                  flagid+=id;
2064                              }
2065                              if(fsnumber!=1) output.print(",");
2066                              output.print(flagid);
2067                              //do the same for tags.
2068                              //maybe not needed because no tag changes tolerated.
2069                          }
2070                          output.println("};\n");
2071                          
2072                          
2073                          //store that information in a struct
2074                          output.println("struct exitstates exitstates"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
2075                          output.println(fsnumber+",");
2076                          output.println("flag_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
2077                          output.println("};\n");
2078
2079                          exitindex++;
2080                      }
2081                      
2082                      //store the information concerning all exits into an array
2083                      output.println("struct exitstates * exitstatesarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2084                      for( int j = 0; j<nbexit; j++){
2085                          if( j != nbexit-1)output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2086                          else output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
2087                      }*/
2088
2089                      int fsnumber = 0 ;
2090                      output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2091                          //iterate through possible FSes corresponding to the state when entering
2092                      for(Iterator fses = otd.flagstates.iterator(); fses.hasNext();){
2093                          FlagState fs = (FlagState)fses.next();
2094                          fsnumber++;
2095                          int flagid=0;
2096                          for(Iterator flags = fs.getFlags(); flags.hasNext();){
2097                              FlagDescriptor flagd = (FlagDescriptor)flags.next();
2098                              int id=1<<((Integer)flaginfo.get(flagd)).intValue();
2099                              flagid+=id;
2100                          }
2101                          if(fsnumber!=1) output.print(",");
2102                          output.print(flagid);
2103                          //tag information not needed because tag changes are not tolerated.
2104                      }
2105                      output.println("};\n");
2106                      
2107                      
2108                      //generate optionaltaskdescriptor that actually includes exit fses, predicate and the task concerned
2109                      output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
2110                      output.println("&task_"+otd.td.getSafeSymbol()+",");
2111                      output.println("/*number of enter flags*/"+fsnumber+",");
2112                      output.println("enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2113                      output.println("/*number of members */"+predicateindex+",");
2114                      output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2115                      //output.println("/*number of exitstates */"+nbexit+",");
2116                      //output.println("/*total number of fses*/"+nbtotal+",");
2117                      //output.println("exitstatesarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
2118                      output.println("};\n");
2119                  }      
2120              }
2121              else continue; // if there is no optionals, there is no need to build the rest of the struct 
2122              
2123              output.println("struct optionaltaskdescriptor * otdarray"+cdtemp.getSafeSymbol()+"[]={");
2124              c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
2125              int x=0;
2126              if( !c_otd.isEmpty() ){
2127                  for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
2128                      OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
2129                      if(x!=0) output.println(",");
2130                      x++;
2131                      output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
2132                  }
2133              }
2134              output.println("};\n");
2135              
2136              //get all the possible falgstates reachable by an object
2137              Hashtable hashtbtemp = safeexecution.get(cdtemp);
2138              Enumeration fses = hashtbtemp.keys();
2139              int fscounter = 0;
2140              while(fses.hasMoreElements()){
2141                  FlagState fs = (FlagState)fses.nextElement();
2142                  fscounter++;
2143                  
2144                  //get the set of OptionalTaskDescriptors corresponding
2145                  HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
2146                  //iterate through the OptionalTaskDescriptors and store the pointers to the optionals struct (see on top) into an array
2147                  
2148                  output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
2149                  for(Iterator mos = availabletasks.iterator(); mos.hasNext();){
2150                      OptionalTaskDescriptor mm = (OptionalTaskDescriptor)mos.next();
2151                      if(!mos.hasNext()) output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol());
2152                      
2153                      else output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2154                  }
2155
2156                  output.println("};\n");
2157                  
2158                  //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
2159                  
2160                  int flagid=0;
2161                  for(Iterator flags = fs.getFlags(); flags.hasNext();){
2162                      FlagDescriptor flagd = (FlagDescriptor)flags.next();
2163                      int id=1<<((Integer)flaginfo.get(flagd)).intValue();
2164                      flagid+=id;
2165                  }
2166                  
2167                  
2168                  //process tag information
2169                  
2170                  int tagcounter = 0;
2171                  boolean first = true;
2172                  Enumeration tag_enum = fs.getTags(); 
2173                  output.println("int tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
2174                  while(tag_enum.hasMoreElements()){
2175                      tagcounter++;
2176                      TagDescriptor tagd = (TagDescriptor)tag_enum.nextElement(); 
2177                      if(first==true)
2178                          first = false;
2179                      else
2180                          output.println(", ");
2181                      output.println("/*tagid*/"+state.getTagId(tagd));
2182                  }
2183                  output.println("};");
2184                  
2185                  
2186                  //Store the result in fsanalysiswrapper
2187                  
2188                  output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
2189                  output.println("/*flag*/"+flagid+",");
2190                  output.println("/* number of tags*/"+tagcounter+",");
2191                  output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
2192                  output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
2193                  output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
2194                  output.println("};\n");
2195                  
2196              }
2197
2198              //Build the array of fsanalysiswrappers
2199              output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
2200              for(int i = 0; i<fscounter; i++){
2201                  if(i==fscounter-1) output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+"};\n");
2202                          
2203                      else output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+",");
2204              }
2205
2206              //Build the classanalysiswrapper referring to the previous array
2207              output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
2208              output.println("/*type*/"+cdtemp.getId()+",");
2209              output.println("/*numotd*/"+numotd+",");
2210              output.println("otdarray"+cdtemp.getSafeSymbol()+",");
2211              output.println("/* number of fsanalysiswrappers */"+fscounter+",");
2212              output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
2213              fscounter = 0;
2214              processedcd.add(cdtemp);
2215          }
2216          
2217          //build an array containing every classes for which code has been build
2218          output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
2219          for(Iterator classit = processedcd.iterator(); classit.hasNext();){
2220              ClassDescriptor cdtemp=(ClassDescriptor)classit.next();
2221              if(!classit.hasNext()) output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol()+"};\n");
2222              else output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol()+",");
2223          }
2224          
2225          output.println("int numclasses="+processedcd.size()+";");
2226          headers.println("extern numclasses;");
2227          output.println("int maxotd="+maxotd+";");
2228          headers.println("extern maxotd;");
2229          headers.println("#endif");
2230         
2231          
2232      }
2233     
2234 }
2235          
2236
2237
2238
2239
2240