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