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