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