OID change
[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         TaskDescriptor task=fm.getTask();
1199
1200         ClassDescriptor cn=md!=null?md.getClassDesc():null;
1201
1202         ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:md!=null?md:task);
1203         generateHeader(fm, lb, md!=null?md:task,output);
1204         TempObject objecttemp=(TempObject) tempstable.get(lb!=null?lb:md!=null?md:task);
1205         if (state.DSM&&lb.getHasAtomic()) {
1206             output.println("transrecord_t * trans;");
1207         }
1208
1209         if (GENERATEPRECISEGC) {
1210             if (md!=null&&state.DSM)
1211                 output.print("   struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1212             else if (md!=null&&!state.DSM)
1213                 output.print("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1214             else
1215                 output.print("   struct "+task.getSafeSymbol()+"_locals "+localsprefix+"={");
1216
1217             output.print(objecttemp.numPointers()+",");
1218             output.print(paramsprefix);
1219             for(int j=0;j<objecttemp.numPointers();j++)
1220                 output.print(", NULL");
1221             output.println("};");
1222         }
1223
1224         for(int i=0;i<objecttemp.numPrimitives();i++) {
1225             TempDescriptor td=objecttemp.getPrimitive(i);
1226             TypeDescriptor type=td.getType();
1227             if (type.isNull())
1228                 output.println("   void * "+td.getSafeSymbol()+";");
1229             else if (type.isClass()||type.isArray())
1230                 output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
1231             else
1232                 output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
1233         }
1234
1235         /* Assign labels to FlatNode's if necessary.*/
1236
1237         Hashtable<FlatNode, Integer> nodetolabel=assignLabels(fm);
1238
1239         /* Check to see if we need to do a GC if this is a
1240          * multi-threaded program...*/
1241
1242         if (state.THREAD&&GENERATEPRECISEGC) {
1243             output.println("checkcollect(&"+localsprefix+");");
1244         }
1245         
1246         /* Do the actual code generation */
1247         FlatNode current_node=null;
1248         HashSet tovisit=new HashSet();
1249         HashSet visited=new HashSet();
1250         tovisit.add(fm.getNext(0));
1251         while(current_node!=null||!tovisit.isEmpty()) {
1252             if (current_node==null) {
1253                 current_node=(FlatNode)tovisit.iterator().next();
1254                 tovisit.remove(current_node);
1255             }
1256             visited.add(current_node);
1257             if (nodetolabel.containsKey(current_node))
1258                 output.println("L"+nodetolabel.get(current_node)+":");
1259             if (state.INSTRUCTIONFAILURE) {
1260                 if (state.THREAD) {
1261                     output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
1262                 }
1263                 else
1264                     output.println("if ((--instructioncount)==0) injectinstructionfailure();");
1265             }
1266             if (current_node.numNext()==0) {
1267                 output.print("   ");
1268                 generateFlatNode(fm, lb, current_node, output);
1269                 if (current_node.kind()!=FKind.FlatReturnNode) {
1270                     output.println("   return;");
1271                 }
1272                 current_node=null;
1273             } else if(current_node.numNext()==1) {
1274                 output.print("   ");
1275                 generateFlatNode(fm, lb, current_node, output);
1276                 FlatNode nextnode=current_node.getNext(0);
1277                 if (visited.contains(nextnode)) {
1278                     output.println("goto L"+nodetolabel.get(nextnode)+";");
1279                     current_node=null;
1280                 } else
1281                     current_node=nextnode;
1282             } else if (current_node.numNext()==2) {
1283                 /* Branch */
1284                 output.print("   ");
1285                 generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
1286                 if (!visited.contains(current_node.getNext(1)))
1287                     tovisit.add(current_node.getNext(1));
1288                 if (visited.contains(current_node.getNext(0))) {
1289                     output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
1290                     current_node=null;
1291                 } else
1292                     current_node=current_node.getNext(0);
1293             } else throw new Error();
1294         }
1295
1296         output.println("}\n\n");
1297     }
1298
1299     /** This method assigns labels to FlatNodes */
1300
1301     private Hashtable<FlatNode, Integer> assignLabels(FlatMethod fm) {
1302         HashSet tovisit=new HashSet();
1303         HashSet visited=new HashSet();
1304         int labelindex=0;
1305         Hashtable<FlatNode, Integer> nodetolabel=new Hashtable<FlatNode, Integer>();
1306         tovisit.add(fm.getNext(0));
1307
1308         /*Assign labels first.  A node needs a label if the previous
1309          * node has two exits or this node is a join point. */
1310
1311         while(!tovisit.isEmpty()) {
1312             FlatNode fn=(FlatNode)tovisit.iterator().next();
1313             tovisit.remove(fn);
1314             visited.add(fn);
1315             for(int i=0;i<fn.numNext();i++) {
1316                 FlatNode nn=fn.getNext(i);
1317                 if(i>0) {
1318                     //1) Edge >1 of node
1319                     nodetolabel.put(nn,new Integer(labelindex++));
1320                 }
1321                 if (!visited.contains(nn)&&!tovisit.contains(nn)) {
1322                     tovisit.add(nn);
1323                 } else {
1324                     //2) Join point
1325                     nodetolabel.put(nn,new Integer(labelindex++));
1326                 }
1327             }
1328         }
1329         return nodetolabel;
1330     }
1331
1332
1333     /** Generate text string that corresponds to the TempDescriptor td. */
1334     private String generateTemp(FlatMethod fm, TempDescriptor td, LocalityBinding lb) {
1335         MethodDescriptor md=fm.getMethod();
1336         TaskDescriptor task=fm.getTask();
1337         TempObject objecttemps=(TempObject) tempstable.get(lb!=null?lb:md!=null?md:task);
1338
1339         if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1340             return td.getSafeSymbol();
1341         }
1342
1343         if (objecttemps.isLocalPtr(td)) {
1344             return localsprefix+"."+td.getSafeSymbol();
1345         }
1346
1347         if (objecttemps.isParamPtr(td)) {
1348             return paramsprefix+"->"+td.getSafeSymbol();
1349         }
1350         throw new Error();
1351     }
1352
1353     private void generateFlatNode(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output) {
1354         switch(fn.kind()) {
1355         case FKind.FlatAtomicEnterNode:
1356             generateFlatAtomicEnterNode(fm, lb, (FlatAtomicEnterNode) fn, output);
1357             return;
1358         case FKind.FlatAtomicExitNode:
1359             generateFlatAtomicExitNode(fm, lb, (FlatAtomicExitNode) fn, output);
1360             return;
1361         case FKind.FlatGlobalConvNode:
1362             generateFlatGlobalConvNode(fm, lb, (FlatGlobalConvNode) fn, output);
1363             return;
1364         case FKind.FlatTagDeclaration:
1365             generateFlatTagDeclaration(fm, lb, (FlatTagDeclaration) fn,output);
1366             return;
1367         case FKind.FlatCall:
1368             generateFlatCall(fm, lb, (FlatCall) fn,output);
1369             return;
1370         case FKind.FlatFieldNode:
1371             generateFlatFieldNode(fm, lb, (FlatFieldNode) fn,output);
1372             return;
1373         case FKind.FlatElementNode:
1374             generateFlatElementNode(fm, lb, (FlatElementNode) fn,output);
1375             return;
1376         case FKind.FlatSetElementNode:
1377             generateFlatSetElementNode(fm, lb, (FlatSetElementNode) fn,output);
1378             return;
1379         case FKind.FlatSetFieldNode:
1380             generateFlatSetFieldNode(fm, lb, (FlatSetFieldNode) fn,output);
1381             return;
1382         case FKind.FlatNew:
1383             generateFlatNew(fm, lb, (FlatNew) fn,output);
1384             return;
1385         case FKind.FlatOpNode:
1386             generateFlatOpNode(fm, lb, (FlatOpNode) fn,output);
1387             return;
1388         case FKind.FlatCastNode:
1389             generateFlatCastNode(fm, lb, (FlatCastNode) fn,output);
1390             return;
1391         case FKind.FlatLiteralNode:
1392             generateFlatLiteralNode(fm, lb, (FlatLiteralNode) fn,output);
1393             return;
1394         case FKind.FlatReturnNode:
1395             generateFlatReturnNode(fm, lb, (FlatReturnNode) fn,output);
1396             return;
1397         case FKind.FlatNop:
1398             output.println("/* nop */");
1399             return;
1400         case FKind.FlatBackEdge:
1401             if ((state.THREAD||state.DSM)&&GENERATEPRECISEGC) {
1402                 output.println("checkcollect(&"+localsprefix+");");
1403             } else
1404                 output.println("/* nop */");
1405             return;
1406         case FKind.FlatCheckNode:
1407             generateFlatCheckNode(fm, lb, (FlatCheckNode) fn, output);
1408             return;
1409         case FKind.FlatFlagActionNode:
1410             generateFlatFlagActionNode(fm, lb, (FlatFlagActionNode) fn, output);
1411             return;
1412         }
1413         throw new Error();
1414
1415     }
1416     
1417     public void generateFlatGlobalConvNode(FlatMethod fm, LocalityBinding lb, FlatGlobalConvNode fgcn, PrintWriter output) {
1418         if (lb!=fgcn.getLocality())
1419             return;
1420         /* Have to generate flat globalconv */
1421         if (fgcn.getMakePtr()) {
1422             output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)transRead(trans, (unsigned int) "+generateTemp(fm, fgcn.getSrc(),lb)+");");
1423         } else {
1424             /* Need to convert to OID */
1425             output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)COMPOID("+generateTemp(fm, fgcn.getSrc(),lb)+");");
1426         }
1427     }
1428
1429     public void generateFlatAtomicEnterNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicEnterNode faen, PrintWriter output) {
1430         /* Check to see if we need to generate code for this atomic */
1431         if (locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
1432             return;
1433         /* Backup the temps. */
1434         for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) {
1435             TempDescriptor tmp=tmpit.next();
1436             output.println(generateTemp(fm, backuptable.get(tmp),lb)+"="+generateTemp(fm,tmp,lb)+";");
1437         }
1438         output.println("goto transstart"+faen.getIdentifier()+";");
1439
1440         /******* Print code to retry aborted transaction *******/
1441         output.println("transretry"+faen.getIdentifier()+":");
1442
1443         /* Restore temps */
1444         for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator();tmpit.hasNext();) {
1445             TempDescriptor tmp=tmpit.next();
1446             output.println(generateTemp(fm, tmp,lb)+"="+generateTemp(fm,backuptable.get(tmp),lb)+";");
1447         }
1448
1449         /********* Need to revert local object store ********/
1450         String revertptr=generateTemp(fm, reverttable.get(lb),lb);
1451         
1452         output.println("while ("+revertptr+") {");
1453         output.println("struct ___Object___ * tmpptr;");
1454         output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
1455         output.println("REVERT_OBJ("+revertptr+");");
1456         output.println(revertptr+"=tmpptr;");
1457         output.println("}");
1458
1459         /******* Tell the runtime to start the transaction *******/
1460         
1461         output.println("transstart"+faen.getIdentifier()+":");
1462         output.println("trans=transStart();");
1463     }
1464
1465     public void generateFlatAtomicExitNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicExitNode faen, PrintWriter output) {
1466         /* Check to see if we need to generate code for this atomic */
1467         if (locality.getAtomic(lb).get(faen).intValue()>0)
1468             return;
1469         //store the revert list before we lose the transaction object
1470         String revertptr=generateTemp(fm, reverttable.get(lb),lb);
1471         output.println(revertptr+"=trans->revertlist;");
1472         output.println("if (transCommit(trans)) {");
1473         /* Transaction aborts if it returns true */
1474         output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
1475         output.println("} else {");
1476         /* Need to commit local object store */
1477         output.println("while ("+revertptr+") {");
1478         output.println("struct ___Object___ * tmpptr;");
1479         output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
1480         output.println("COMMIT_OBJ("+revertptr+");");
1481         output.println(revertptr+"=tmpptr;");
1482         output.println("}");
1483         output.println("}");
1484     }
1485
1486     private void generateFlatCheckNode(FlatMethod fm,  LocalityBinding lb, FlatCheckNode fcn, PrintWriter output) {
1487         if (state.CONSCHECK) {
1488             String specname=fcn.getSpec();
1489             String varname="repairstate___";
1490             output.println("{");
1491             output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
1492
1493             TempDescriptor[] temps=fcn.getTemps();
1494             String[] vars=fcn.getVars();
1495             for(int i=0;i<temps.length;i++) {
1496                 output.println(varname+"->"+vars[i]+"=(unsigned int)"+generateTemp(fm, temps[i],lb)+";");
1497             }
1498
1499             output.println("if (doanalysis"+specname+"("+varname+")) {");
1500             output.println("free"+specname+"_state("+varname+");");
1501             output.println("} else {");
1502             output.println("/* Bad invariant */");
1503             output.println("free"+specname+"_state("+varname+");");
1504             output.println("abort_task();");
1505             output.println("}");
1506             output.println("}");
1507         }
1508     }
1509
1510     private void generateFlatCall(FlatMethod fm, LocalityBinding lb, FlatCall fc, PrintWriter output) {
1511         MethodDescriptor md=fc.getMethod();
1512         ParamsObject objectparams=(ParamsObject)paramstable.get(state.DSM?locality.getBinding(lb, fc):md);
1513         ClassDescriptor cn=md.getClassDesc();
1514         output.println("{");
1515         if (GENERATEPRECISEGC) {
1516             if (state.DSM) {
1517                 LocalityBinding fclb=locality.getBinding(lb, fc);
1518                 output.print("       struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
1519             } else
1520                 output.print("       struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
1521             
1522             output.print(objectparams.numPointers());
1523             output.print(", & "+localsprefix);
1524             if (fc.getThis()!=null) {
1525                 output.print(", ");
1526                 output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis(),lb));
1527             }
1528             for(int i=0;i<fc.numArgs();i++) {
1529                 Descriptor var=md.getParameter(i);
1530                 TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1531                 if (objectparams.isParamPtr(paramtemp)) {
1532                     TempDescriptor targ=fc.getArg(i);
1533                     output.print(", ");
1534                     TypeDescriptor td=md.getParamType(i);
1535                     if (td.isTag())
1536                         output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()  +" *)"+generateTemp(fm, targ,lb));
1537                     else
1538                         output.print("(struct "+md.getParamType(i).getSafeSymbol()  +" *)"+generateTemp(fm, targ,lb));
1539                 }
1540             }
1541             output.println("};");
1542         }
1543         output.print("       ");
1544
1545
1546         if (fc.getReturnTemp()!=null)
1547             output.print(generateTemp(fm,fc.getReturnTemp(),lb)+"=");
1548
1549         /* Do we need to do virtual dispatch? */
1550         if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
1551             //no
1552             if (state.DSM) {
1553                 LocalityBinding fclb=locality.getBinding(lb, fc);
1554                 output.print(cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
1555             } else {
1556                 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
1557             }
1558         } else {
1559             //yes
1560             output.print("((");
1561             if (md.getReturnType().isClass()||md.getReturnType().isArray())
1562                 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1563             else
1564                 output.print(md.getReturnType().getSafeSymbol()+" ");
1565             output.print("(*)(");
1566
1567             boolean printcomma=false;
1568             if (GENERATEPRECISEGC) {
1569                 if (state.DSM) {
1570                     LocalityBinding fclb=locality.getBinding(lb, fc);
1571                     output.print("struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
1572                 } else
1573                     output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
1574                 printcomma=true;
1575             }
1576
1577             for(int i=0;i<objectparams.numPrimitives();i++) {
1578                 TempDescriptor temp=objectparams.getPrimitive(i);
1579                 if (printcomma)
1580                     output.print(", ");
1581                 printcomma=true;
1582                 if (temp.getType().isClass()||temp.getType().isArray())
1583                     output.print("struct " + temp.getType().getSafeSymbol()+" * ");
1584                 else
1585                     output.print(temp.getType().getSafeSymbol());
1586             }
1587
1588             if (state.DSM) {
1589                 LocalityBinding fclb=locality.getBinding(lb, fc);
1590                 output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getLocalityNumber(fclb)+"])");
1591             } else
1592                 output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
1593         }
1594
1595         output.print("(");
1596         boolean needcomma=false;
1597         if (GENERATEPRECISEGC) {
1598             output.print("&__parameterlist__");
1599             needcomma=true;
1600         }
1601
1602         if (state.DSM&&locality.getBinding(lb,fc).isAtomic()) {
1603             if (needcomma)
1604                 output.print(",");
1605             output.print("trans");
1606             needcomma=true;
1607         }
1608
1609         if (!GENERATEPRECISEGC) {
1610             if (fc.getThis()!=null) {
1611                 TypeDescriptor ptd=md.getThis().getType();
1612                 if (needcomma)
1613                     output.print(",");
1614                 if (ptd.isClass()&&!ptd.isArray())
1615                     output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1616                 output.print(generateTemp(fm,fc.getThis(),lb));
1617                 needcomma=true;
1618             }
1619         }
1620
1621         for(int i=0;i<fc.numArgs();i++) {
1622             Descriptor var=md.getParameter(i);
1623             TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
1624             if (objectparams.isParamPrim(paramtemp)) {
1625                 TempDescriptor targ=fc.getArg(i);
1626                 if (needcomma)
1627                     output.print(", ");
1628
1629                 TypeDescriptor ptd=md.getParamType(i);
1630                 if (ptd.isClass()&&!ptd.isArray())
1631                     output.print("(struct "+ptd.getSafeSymbol()+" *) ");
1632                 output.print(generateTemp(fm, targ,lb));
1633                 needcomma=true;
1634             }
1635         }
1636         output.println(");");
1637         output.println("   }");
1638     }
1639
1640     private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
1641         Set subclasses=typeutil.getSubClasses(thiscd);
1642         if (subclasses==null)
1643             return true;
1644         for(Iterator classit=subclasses.iterator();classit.hasNext();) {
1645             ClassDescriptor cd=(ClassDescriptor)classit.next();
1646             Set possiblematches=cd.getMethodTable().getSet(md.getSymbol());
1647             for(Iterator matchit=possiblematches.iterator();matchit.hasNext();) {
1648                 MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
1649                 if (md.matches(matchmd))
1650                     return false;
1651             }
1652         }
1653         return true;
1654     }
1655
1656     private void generateFlatFieldNode(FlatMethod fm, LocalityBinding lb, FlatFieldNode ffn, PrintWriter output) {
1657         if (state.DSM) {
1658             Integer status=locality.getNodePreTempInfo(lb,ffn).get(ffn.getSrc());
1659             if (status==LocalityAnalysis.GLOBAL) {
1660                 String field=ffn.getField().getSafeSymbol();
1661                 String src="((struct "+ffn.getSrc().getType().getSafeSymbol()+" *)((unsigned int)"+generateTemp(fm, ffn.getSrc(),lb)+"+sizeof(objheader_t)))";
1662                 String dst=generateTemp(fm, ffn.getDst(),lb);
1663                     
1664                 if (ffn.getField().getType().isPtr()||
1665                     ffn.getField().getType().isArray()) {
1666
1667                     //TODO: Uncomment this when we have runtime support
1668                     //if (ffn.getSrc()==ffn.getDst()) {
1669                     //output.println("{");
1670                     //output.println("void * temp="+src+";");
1671                     //output.println("if (temp&0x1) {");
1672                     //output.println("temp=(void *) transRead(trans, (unsigned int) temp);");
1673                     //output.println(src+"->"+field+"="+temp+";");
1674                     //output.println("}");
1675                     //output.println(dst+"=temp;");
1676                     //output.println("}");
1677                     //} else {
1678                     output.println(dst+"="+ src +"->"+field+ ";");
1679                     //output.println("if ("+dst+"&0x1) {");
1680                     output.println(dst+"=(void *) transRead(trans, (unsigned int) "+dst+");");
1681                     //output.println(src+"->"+field+"="+src+"->"+field+";");
1682                     //output.println("}");
1683                     //}
1684                 } else {
1685                     output.println(dst+"="+ src+"->"+field+";");
1686                 }
1687             } else if (status==LocalityAnalysis.LOCAL) {
1688                 output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
1689             } else if (status==LocalityAnalysis.EITHER) {
1690                 //Code is reading from a null pointer
1691                 output.println("if ("+generateTemp(fm, ffn.getSrc(),lb)+") {");
1692                 output.println("printf(\"BIG ERROR\n\");exit(-1);}");
1693                 //This should throw a suitable null pointer error
1694                 output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
1695             } else
1696                 throw new Error("Read from non-global/non-local in:"+lb.getExplanation());
1697         } else
1698             output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
1699     }
1700
1701     private void generateFlatSetFieldNode(FlatMethod fm, LocalityBinding lb, FlatSetFieldNode fsfn, PrintWriter output) {
1702         if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
1703             throw new Error("Can't set array length");
1704         if (state.DSM && locality.getAtomic(lb).get(fsfn).intValue()>0) {
1705             Integer statussrc=locality.getNodePreTempInfo(lb,fsfn).get(fsfn.getSrc());
1706             Integer statusdst=locality.getNodeTempInfo(lb).get(fsfn).get(fsfn.getDst());
1707             boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL;
1708
1709             String src=generateTemp(fm,fsfn.getSrc(),lb);
1710             String dst=generateTemp(fm,fsfn.getDst(),lb);
1711             if (srcglobal) {
1712                 output.println("{");
1713                 output.println("int srcoid="+src+"->"+oidstr+";");
1714             }
1715             if (statusdst.equals(LocalityAnalysis.GLOBAL)) {
1716                 String glbdst="((struct "+fsfn.getDst().getType().getSafeSymbol()+" *)((unsigned int)"+dst+" +sizeof(objheader_t)))";
1717                 //mark it dirty
1718                 output.println("*((unsigned int *)&("+dst+"->___localcopy___))|=DIRTY;");
1719                 if (srcglobal) {
1720                     output.println("*((unsigned int *)&("+glbdst+"->"+ fsfn.getField().getSafeSymbol()+"))=srcoid;");
1721                     output.println("}");
1722                 } else
1723                     output.println(glbdst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");          
1724             } else if (statusdst.equals(LocalityAnalysis.LOCAL)) {
1725                 /** Check if we need to copy */
1726                 output.println("if(!"+dst+"->"+localcopystr+") {");
1727                 /* Link object into list */
1728                 output.println(dst+"->"+nextobjstr+"=trans->localtrans;");
1729                 output.println("trans->localtrans="+dst+";");
1730                 if (GENERATEPRECISEGC)
1731                     output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
1732                 else
1733                     output.println("COPY_OBJ("+dst+");");
1734                 output.println("}");
1735                 if (srcglobal)
1736                     output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=srcoid;");
1737                 else
1738                     output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
1739             } else if (statusdst.equals(LocalityAnalysis.EITHER)) {
1740                 //writing to a null...bad
1741                 output.println("if ("+dst+") {");
1742                 output.println("printf(\"BIG ERROR 2\n\");exit(-1);}");
1743                 if (srcglobal)
1744                     output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=srcoid;");
1745                 else
1746                     output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
1747             }
1748             if (srcglobal) {
1749                 output.println("}");
1750             }
1751         } else {
1752             output.println(generateTemp(fm, fsfn.getDst(),lb)+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";");
1753         }
1754     }
1755
1756     private void generateFlatElementNode(FlatMethod fm, LocalityBinding lb, FlatElementNode fen, PrintWriter output) {
1757         TypeDescriptor elementtype=fen.getSrc().getType().dereference();
1758         String type="";
1759
1760         if (elementtype.isArray()||elementtype.isClass())
1761             type="void *";
1762         else 
1763             type=elementtype.getSafeSymbol()+" ";
1764
1765         if (fen.needsBoundsCheck()) {
1766             output.println("if ("+generateTemp(fm, fen.getIndex(),lb)+"< 0 || "+generateTemp(fm, fen.getIndex(),lb)+" >= "+generateTemp(fm,fen.getSrc(),lb) + "->___length___)");
1767             output.println("failedboundschk();");
1768         }
1769
1770         output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
1771     }
1772
1773     private void generateFlatSetElementNode(FlatMethod fm, LocalityBinding lb, FlatSetElementNode fsen, PrintWriter output) {
1774         //TODO: need dynamic check to make sure this assignment is actually legal
1775         //Because Object[] could actually be something more specific...ie. Integer[]
1776
1777         TypeDescriptor elementtype=fsen.getDst().getType().dereference();
1778         String type="";
1779
1780         if (elementtype.isArray()||elementtype.isClass())
1781             type="void *";
1782         else 
1783             type=elementtype.getSafeSymbol()+" ";
1784
1785         if (fsen.needsBoundsCheck()) {
1786             output.println("if ("+generateTemp(fm, fsen.getIndex(),lb)+"< 0 || "+generateTemp(fm, fsen.getIndex(),lb)+" >= "+generateTemp(fm,fsen.getDst(),lb) + "->___length___)");
1787             output.println("failedboundschk();");
1788         }
1789
1790         output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
1791     }
1792
1793     private void generateFlatNew(FlatMethod fm, LocalityBinding lb, FlatNew fn, PrintWriter output) {
1794         if (fn.getType().isArray()) {
1795             int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
1796             if (fn.isGlobal()) {
1797                 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarrayglobal(trans, "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
1798             } else if (GENERATEPRECISEGC) {
1799                 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
1800             } else {
1801                 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
1802             }
1803         } else {
1804             if (fn.isGlobal()) {
1805                 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newglobal(trans, "+fn.getType().getClassDesc().getId()+");");
1806             } else if (GENERATEPRECISEGC) {
1807                 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
1808             } else {
1809                 output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
1810             }
1811         }
1812     }
1813
1814     private void generateFlatTagDeclaration(FlatMethod fm, LocalityBinding lb, FlatTagDeclaration fn, PrintWriter output) {
1815         if (GENERATEPRECISEGC) {
1816             output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag(&"+localsprefix+", "+state.getTagId(fn.getType())+");");
1817         } else {
1818             output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag("+state.getTagId(fn.getType())+");");
1819         }
1820     }
1821
1822     private void generateFlatOpNode(FlatMethod fm, LocalityBinding lb, FlatOpNode fon, PrintWriter output) {
1823         if (fon.getRight()!=null)
1824             output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+fon.getOp().toString()+generateTemp(fm,fon.getRight(),lb)+";");
1825         else if (fon.getOp().getOp()==Operation.ASSIGN)
1826             output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
1827         else if (fon.getOp().getOp()==Operation.UNARYPLUS)
1828             output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
1829         else if (fon.getOp().getOp()==Operation.UNARYMINUS)
1830             output.println(generateTemp(fm, fon.getDest(),lb)+" = -"+generateTemp(fm, fon.getLeft(),lb)+";");
1831         else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
1832             output.println(generateTemp(fm, fon.getDest(),lb)+" = !"+generateTemp(fm, fon.getLeft(),lb)+";");
1833         else
1834             output.println(generateTemp(fm, fon.getDest(),lb)+fon.getOp().toString()+generateTemp(fm, fon.getLeft(),lb)+";");
1835     }
1836
1837     private void generateFlatCastNode(FlatMethod fm, LocalityBinding lb, FlatCastNode fcn, PrintWriter output) {
1838         /* TODO: Do type check here */
1839         if (fcn.getType().isArray()) {
1840             throw new Error();
1841         } else if (fcn.getType().isClass())
1842             output.println(generateTemp(fm,fcn.getDst(),lb)+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc(),lb)+";");
1843         else
1844             output.println(generateTemp(fm,fcn.getDst(),lb)+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc(),lb)+";");
1845     }
1846
1847     private void generateFlatLiteralNode(FlatMethod fm, LocalityBinding lb, FlatLiteralNode fln, PrintWriter output) {
1848         if (fln.getValue()==null)
1849             output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
1850         else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
1851             if (GENERATEPRECISEGC) {
1852                 output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1853             } else {
1854                 output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
1855             }
1856         } else if (fln.getType().isBoolean()) {
1857             if (((Boolean)fln.getValue()).booleanValue())
1858                 output.println(generateTemp(fm, fln.getDst(),lb)+"=1;");
1859             else
1860                 output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
1861         } else if (fln.getType().isChar()) {
1862             String st=FlatLiteralNode.escapeString(fln.getValue().toString());
1863             output.println(generateTemp(fm, fln.getDst(),lb)+"='"+st+"';");
1864         } else
1865             output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+";");
1866     }
1867
1868     private void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
1869         if (frn.getReturnTemp()!=null)
1870             output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
1871         else
1872             output.println("return;");
1873     }
1874
1875     private void generateFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) {
1876         output.println("if (!"+generateTemp(fm, fcb.getTest(),lb)+") goto "+label+";");
1877     }
1878
1879     /** This method generates header information for the method or
1880      * task referenced by the Descriptor des. */
1881
1882     private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
1883         /* Print header */
1884         ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null?lb:des);
1885         MethodDescriptor md=null;
1886         TaskDescriptor task=null;
1887         if (des instanceof MethodDescriptor)
1888             md=(MethodDescriptor) des;
1889         else
1890             task=(TaskDescriptor) des;
1891
1892         ClassDescriptor cn=md!=null?md.getClassDesc():null;
1893         
1894         if (md!=null&&md.getReturnType()!=null) {
1895             if (md.getReturnType().isClass()||md.getReturnType().isArray())
1896                 output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1897             else
1898                 output.print(md.getReturnType().getSafeSymbol()+" ");
1899         } else 
1900             //catch the constructor case
1901             output.print("void ");
1902         if (md!=null) {
1903             if (state.DSM) {
1904                 output.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1905             } else
1906                 output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1907         } else
1908             output.print(task.getSafeSymbol()+"(");
1909         
1910         boolean printcomma=false;
1911         if (GENERATEPRECISEGC) {
1912             if (md!=null) {
1913                 if (state.DSM) {
1914                     output.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1915                 } else
1916                     output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1917             } else
1918                 output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1919             printcomma=true;
1920         }
1921
1922         if (state.DSM&&lb.isAtomic()) {
1923             if (printcomma)
1924                 output.print(", ");
1925             output.print("transrecord_t * trans");
1926             printcomma=true;
1927         }
1928
1929         if (md!=null) {
1930             /* Method */
1931             for(int i=0;i<objectparams.numPrimitives();i++) {
1932                 TempDescriptor temp=objectparams.getPrimitive(i);
1933                 if (printcomma)
1934                     output.print(", ");
1935                 printcomma=true;
1936                 if (temp.getType().isClass()||temp.getType().isArray())
1937                     output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1938                 else
1939                     output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1940             }
1941             output.println(") {");
1942         } else if (!GENERATEPRECISEGC) {
1943             /* Imprecise Task */
1944             output.println("void * parameterarray[]) {");
1945             /* Unpack variables */
1946             for(int i=0;i<objectparams.numPrimitives();i++) {
1947                 TempDescriptor temp=objectparams.getPrimitive(i);
1948                 output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
1949             }
1950             for(int i=0;i<fm.numTags();i++) {
1951                 TempDescriptor temp=fm.getTag(i);
1952                 int offset=i+objectparams.numPrimitives();
1953                 output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
1954             }
1955
1956             if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
1957                 maxtaskparams=objectparams.numPrimitives()+fm.numTags();
1958         } else output.println(") {");
1959     }
1960     
1961     public void generateFlatFlagActionNode(FlatMethod fm, LocalityBinding lb, FlatFlagActionNode ffan, PrintWriter output) {
1962         output.println("/* FlatFlagActionNode */");
1963
1964
1965         /* Process tag changes */
1966         Relation tagsettable=new Relation();
1967         Relation tagcleartable=new Relation();
1968
1969         Iterator tagsit=ffan.getTempTagPairs(); 
1970         while (tagsit.hasNext()) {
1971             TempTagPair ttp=(TempTagPair) tagsit.next();
1972             TempDescriptor objtmp=ttp.getTemp();
1973             TagDescriptor tag=ttp.getTag();
1974             TempDescriptor tagtmp=ttp.getTagTemp();
1975             boolean tagstatus=ffan.getTagChange(ttp);
1976             if (tagstatus) {
1977                 tagsettable.put(objtmp, tagtmp);
1978             } else {
1979                 tagcleartable.put(objtmp, tagtmp);
1980             }
1981         }
1982
1983
1984         Hashtable flagandtable=new Hashtable();
1985         Hashtable flagortable=new Hashtable();
1986
1987         /* Process flag changes */
1988         Iterator flagsit=ffan.getTempFlagPairs();
1989         while(flagsit.hasNext()) {
1990             TempFlagPair tfp=(TempFlagPair)flagsit.next();
1991             TempDescriptor temp=tfp.getTemp();
1992             Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
1993             FlagDescriptor flag=tfp.getFlag();
1994             if (flag==null) {
1995                 //Newly allocate objects that don't set any flags case
1996                 if (flagortable.containsKey(temp)) {
1997                     throw new Error();
1998                 }
1999                 int mask=0;
2000                 flagortable.put(temp,new Integer(mask));
2001             } else {
2002                 int flagid=1<<((Integer)flagtable.get(flag)).intValue();
2003                 boolean flagstatus=ffan.getFlagChange(tfp);
2004                 if (flagstatus) {
2005                     int mask=0;
2006                     if (flagortable.containsKey(temp)) {
2007                         mask=((Integer)flagortable.get(temp)).intValue();
2008                     }
2009                     mask|=flagid;
2010                     flagortable.put(temp,new Integer(mask));
2011                 } else {
2012                     int mask=0xFFFFFFFF;
2013                     if (flagandtable.containsKey(temp)) {
2014                         mask=((Integer)flagandtable.get(temp)).intValue();
2015                     }
2016                     mask&=(0xFFFFFFFF^flagid);
2017                     flagandtable.put(temp,new Integer(mask));
2018                 }
2019             }
2020         }
2021
2022
2023         HashSet flagtagset=new HashSet();
2024         flagtagset.addAll(flagortable.keySet());
2025         flagtagset.addAll(flagandtable.keySet());
2026         flagtagset.addAll(tagsettable.keySet());
2027         flagtagset.addAll(tagcleartable.keySet());
2028
2029         Iterator ftit=flagtagset.iterator();
2030         while(ftit.hasNext()) {
2031             TempDescriptor temp=(TempDescriptor)ftit.next();
2032             
2033             
2034             Set tagtmps=tagcleartable.get(temp);
2035             if (tagtmps!=null) {
2036                 Iterator tagit=tagtmps.iterator();
2037                 while(tagit.hasNext()) {
2038                     TempDescriptor tagtmp=(TempDescriptor)tagit.next();
2039                     if (GENERATEPRECISEGC) 
2040                         output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
2041                     else
2042                         output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
2043                 }
2044             }
2045
2046             tagtmps=tagsettable.get(temp);
2047             if (tagtmps!=null) {
2048                 Iterator tagit=tagtmps.iterator();
2049                 while(tagit.hasNext()) {
2050                     TempDescriptor tagtmp=(TempDescriptor)tagit.next();
2051                     if (GENERATEPRECISEGC)
2052                         output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
2053                     else
2054                         output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp, lb)+", "+generateTemp(fm,tagtmp, lb)+");");
2055                 }
2056             }
2057
2058             int ormask=0;
2059             int andmask=0xFFFFFFF;
2060             
2061             if (flagortable.containsKey(temp))
2062                 ormask=((Integer)flagortable.get(temp)).intValue();
2063             if (flagandtable.containsKey(temp))
2064                 andmask=((Integer)flagandtable.get(temp)).intValue();
2065             if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
2066                 output.println("flagorandinit("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
2067             } else {
2068                 output.println("flagorand("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
2069             }
2070         }
2071     }
2072
2073      void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, HashSet>> safeexecution, Hashtable optionaltaskdescriptors) {
2074          
2075          //GENERATE HEADERS
2076          headers.println("#include \"task.h\"\n\n");
2077          headers.println("#ifndef _OPTIONAL_STRUCT_");
2078          headers.println("#define _OPTIONAL_STRUCT_");
2079          
2080          
2081          
2082          
2083          //STRUCT PREDICATEMEMBER
2084          headers.println("struct predicatemember{");
2085          headers.println("int type;");
2086          headers.println("int numdnfterms;");
2087          headers.println("int * flags;");
2088          headers.println("int numtags;");
2089          headers.println("int * tags;\n};\n\n");
2090
2091          /*//STRUCT EXITSTATES
2092          headers.println("struct exitstates{");
2093          headers.println("int numflagstates;");
2094          headers.println("int * flagstatearray;\n};\n\n");*///appeared to be useless
2095
2096          //STRUCT OPTIONALTASKDESCRIPTOR
2097          headers.println("struct optionaltaskdescriptor{");
2098          headers.println("struct taskdescriptor * task;");
2099          headers.println("int numenterflags;");
2100          headers.println("int * enterflags;");
2101          headers.println("int numpredicatemembers;");
2102          headers.println("struct predicatemember ** predicatememberarray;");
2103          //headers.println("int numexitstates;");
2104          //headers.println("int numTotal;");
2105          //headers.println("struct exitstates ** exitstatesarray;\n};\n\n");
2106          headers.println("\n};\n\n");
2107                  
2108          //STRUCT FSANALYSISWRAPPER
2109          headers.println("struct fsanalysiswrapper{");
2110          headers.println("int  flags;");
2111          headers.println("int numtags;");
2112          headers.println("int * tags;");
2113          headers.println("int numoptionaltaskdescriptors;");
2114          headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
2115
2116          //STRUCT CLASSANALYSISWRAPPER
2117          headers.println("struct classanalysiswrapper{");
2118          headers.println("int type;");
2119          headers.println("int numotd;");
2120          headers.println("struct optionaltaskdescriptor ** otdarray;");
2121          headers.println("int numfsanalysiswrappers;");
2122          headers.println("struct fsanalysiswrapper ** fsanalysiswrapperarray;\n};");
2123          
2124          headers.println("extern struct classanalysiswrapper * classanalysiswrapperarray[];");
2125
2126          Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
2127          while(taskit.hasNext()) {
2128              TaskDescriptor td=(TaskDescriptor)taskit.next();
2129              headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
2130          }
2131          
2132          
2133          //GENERATE STRUCTS
2134          if (state.OPTIONAL)
2135              output.println("#include \"optionalstruct.h\"\n\n");        
2136          HashSet processedcd = new HashSet();
2137         
2138          int maxotd=0;
2139          Enumeration e = safeexecution.keys();
2140          while (e.hasMoreElements()) {
2141              int numotd=0;
2142              //get the class
2143              ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
2144              Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);//will be used several times
2145              
2146              //////////////////////////DEBUG
2147              System.out.println(cdtemp.getSymbol()+" "+cdtemp.getId());
2148              for(Iterator flags = cdtemp.getFlags(); flags.hasNext();){
2149                  FlagDescriptor flagd = (FlagDescriptor)flags.next();
2150                  int flagid=1<<((Integer)flaginfo.get(flagd)).intValue();
2151                  System.out.println(" Flag "+flagd.getSymbol()+" 0x"+Integer.toHexString(flagid)+" int "+flagid);
2152              }
2153              ///////////////////////////
2154              
2155              //Generate the struct of optionals
2156              if((Hashtable)optionaltaskdescriptors.get(cdtemp)==null) System.out.println("Was in cd :"+cdtemp.getSymbol());
2157              Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
2158              numotd = c_otd.size();
2159              if(maxotd<numotd) maxotd = numotd; 
2160              if( !c_otd.isEmpty() ){
2161                  for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
2162                      OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
2163                      
2164                      //generate the int arrays for the predicate
2165                      Predicate predicate = otd.predicate;
2166                      int predicateindex = 0;
2167                      //iterate through the classes concerned by the predicate
2168                      Collection c_vard = predicate.vardescriptors.values();
2169                      for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();){
2170                          VarDescriptor vard = (VarDescriptor)vard_it.next();
2171                          TypeDescriptor typed = vard.getType();
2172                          
2173                          //generate for flags
2174                          HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
2175                          output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2176                          int numberterms=0;
2177                          if (fen_hashset!=null){
2178                              for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();){
2179                                  FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
2180                                  if (fen==null) {
2181                                  }    
2182                                  else {
2183                                      
2184                                      DNFFlag dflag=fen.getDNF();
2185                                      numberterms+=dflag.size();
2186                                      
2187                                      Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
2188                                      
2189                                      for(int j=0;j<dflag.size();j++) {
2190                                          if (j!=0)
2191                                              output.println(",");
2192                                          Vector term=dflag.get(j);
2193                                          int andmask=0;
2194                                          int checkmask=0;
2195                                          for(int k=0;k<term.size();k++) {
2196                                              DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
2197                                              FlagDescriptor fd=dfa.getFlag();
2198                                              boolean negated=dfa.getNegated();
2199                                              int flagid=1<<((Integer)flags.get(fd)).intValue();
2200                                              andmask|=flagid;
2201                                              if (!negated)
2202                                                  checkmask|=flagid;
2203                                          }
2204                                          output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
2205                                      }
2206                                  }
2207                              }
2208                          }
2209                          output.println("};\n");
2210                          
2211                          //generate for tags
2212                          TagExpressionList tagel = predicate.tags.get(vard.getSymbol()); 
2213                          output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2214                          //BUG...added next line to fix, test with any task program
2215                          int numtags = 0;
2216                          if (tagel!=null){
2217                              for(int j=0;j<tagel.numTags();j++) {
2218                                  if (j!=0)
2219                                      output.println(",");
2220                                  TempDescriptor tmp=tagel.getTemp(j);
2221                                  //got rid of slot, maybe some improvments to do ???
2222                                  output.println("/*tagid*/"+state.getTagId(tmp.getTag()));
2223                              }
2224                              numtags = tagel.numTags();
2225                          }
2226                          output.println("};");
2227                          
2228                          //store the result into a predicatemember struct
2229                          output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
2230                          output.println("/*type*/"+typed.getClassDesc().getId()+",");
2231                          output.println("/* number of dnf terms */"+numberterms+",");
2232                          output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2233                          output.println("/* number of tag */"+numtags+",");
2234                          output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2235                          output.println("};\n");
2236                          predicateindex++;
2237                      }
2238                      
2239
2240                      //generate an array that stores the entire predicate
2241                      output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2242                      for( int j = 0; j<predicateindex; j++){
2243                          if( j != predicateindex-1)output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2244                          else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
2245                      }
2246                      output.println("};\n");
2247
2248                      //generate the struct for possible exitfses, appeared to be useless
2249                      /*HashSet<HashSet> exitfses = otd.exitfses;
2250                      int exitindex = 0;
2251                      int nbexit = exitfses.size();
2252                      int fsnumber;
2253                      
2254                      //iterate through possible exits
2255                      int nbtotal=0;
2256                      for(Iterator exitfseshash = exitfses.iterator(); exitfseshash.hasNext();){
2257                          HashSet temp_hashset = (HashSet)exitfseshash.next();
2258                          fsnumber = 0 ;
2259                          output.println("int flag_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2260                          //iterate through possible FSes corresponding to the exit
2261                          for(Iterator exfses = temp_hashset.iterator(); exfses.hasNext();){
2262                              FlagState fs = (FlagState)exfses.next();
2263                              fsnumber++;
2264                              nbtotal++;
2265                              int flagid=0;
2266                              for(Iterator flags = fs.getFlags(); flags.hasNext();){
2267                                  FlagDescriptor flagd = (FlagDescriptor)flags.next();
2268                                  int id=1<<((Integer)flaginfo.get(flagd)).intValue();
2269                                  flagid+=id;
2270                              }
2271                              if(fsnumber!=1) output.print(",");
2272                              output.print(flagid);
2273                              //do the same for tags.
2274                              //maybe not needed because no tag changes tolerated.
2275                          }
2276                          output.println("};\n");
2277                          
2278                          
2279                          //store that information in a struct
2280                          output.println("struct exitstates exitstates"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
2281                          output.println(fsnumber+",");
2282                          output.println("flag_EXIT"+exitindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
2283                          output.println("};\n");
2284
2285                          exitindex++;
2286                      }
2287                      
2288                      //store the information concerning all exits into an array
2289                      output.println("struct exitstates * exitstatesarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2290                      for( int j = 0; j<nbexit; j++){
2291                          if( j != nbexit-1)output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2292                          else output.println("&exitstates"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"};\n");
2293                      }*/
2294
2295                      int fsnumber = 0 ;
2296                      output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2297                          //iterate through possible FSes corresponding to the state when entering
2298                      for(Iterator fses = otd.flagstates.iterator(); fses.hasNext();){
2299                          FlagState fs = (FlagState)fses.next();
2300                          fsnumber++;
2301                          int flagid=0;
2302                          for(Iterator flags = fs.getFlags(); flags.hasNext();){
2303                              FlagDescriptor flagd = (FlagDescriptor)flags.next();
2304                              int id=1<<((Integer)flaginfo.get(flagd)).intValue();
2305                              flagid+=id;
2306                          }
2307                          if(fsnumber!=1) output.print(",");
2308                          output.print(flagid);
2309                          //tag information not needed because tag changes are not tolerated.
2310                      }
2311                      output.println("};\n");
2312                      
2313                      
2314                      //generate optionaltaskdescriptor that actually includes exit fses, predicate and the task concerned
2315                      output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
2316                      output.println("&task_"+otd.td.getSafeSymbol()+",");
2317                      output.println("/*number of enter flags*/"+fsnumber+",");
2318                      output.println("enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2319                      output.println("/*number of members */"+predicateindex+",");
2320                      output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2321                      //output.println("/*number of exitstates */"+nbexit+",");
2322                      //output.println("/*total number of fses*/"+nbtotal+",");
2323                      //output.println("exitstatesarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
2324                      output.println("};\n");
2325                  }      
2326              }
2327              else continue; // if there is no optionals, there is no need to build the rest of the struct 
2328              
2329              output.println("struct optionaltaskdescriptor * otdarray"+cdtemp.getSafeSymbol()+"[]={");
2330              c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
2331              int x=0;
2332              if( !c_otd.isEmpty() ){
2333                  for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();){
2334                      OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
2335                      if(x!=0) output.println(",");
2336                      x++;
2337                      output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
2338                  }
2339              }
2340              output.println("};\n");
2341              
2342              //get all the possible falgstates reachable by an object
2343              Hashtable hashtbtemp = safeexecution.get(cdtemp);
2344              Enumeration fses = hashtbtemp.keys();
2345              int fscounter = 0;
2346              while(fses.hasMoreElements()){
2347                  FlagState fs = (FlagState)fses.nextElement();
2348                  fscounter++;
2349                  
2350                  //get the set of OptionalTaskDescriptors corresponding
2351                  HashSet availabletasks = (HashSet)hashtbtemp.get(fs);
2352                  //iterate through the OptionalTaskDescriptors and store the pointers to the optionals struct (see on top) into an array
2353                  
2354                  output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
2355                  for(Iterator mos = availabletasks.iterator(); mos.hasNext();){
2356                      OptionalTaskDescriptor mm = (OptionalTaskDescriptor)mos.next();
2357                      if(!mos.hasNext()) output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol());
2358                      
2359                      else output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
2360                  }
2361
2362                  output.println("};\n");
2363                  
2364                  //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
2365                  
2366                  int flagid=0;
2367                  for(Iterator flags = fs.getFlags(); flags.hasNext();){
2368                      FlagDescriptor flagd = (FlagDescriptor)flags.next();
2369                      int id=1<<((Integer)flaginfo.get(flagd)).intValue();
2370                      flagid+=id;
2371                  }
2372                  
2373                  
2374                  //process tag information
2375                  
2376                  int tagcounter = 0;
2377                  boolean first = true;
2378                  Enumeration tag_enum = fs.getTags(); 
2379                  output.println("int tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
2380                  while(tag_enum.hasMoreElements()){
2381                      tagcounter++;
2382                      TagDescriptor tagd = (TagDescriptor)tag_enum.nextElement(); 
2383                      if(first==true)
2384                          first = false;
2385                      else
2386                          output.println(", ");
2387                      output.println("/*tagid*/"+state.getTagId(tagd));
2388                  }
2389                  output.println("};");
2390                  
2391                  
2392                  //Store the result in fsanalysiswrapper
2393                  
2394                  output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
2395                  output.println("/*flag*/"+flagid+",");
2396                  output.println("/* number of tags*/"+tagcounter+",");
2397                  output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
2398                  output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
2399                  output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
2400                  output.println("};\n");
2401                  
2402              }
2403
2404              //Build the array of fsanalysiswrappers
2405              output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
2406              for(int i = 0; i<fscounter; i++){
2407                  if(i==fscounter-1) output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+"};\n");
2408                          
2409                      else output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol()+",");
2410              }
2411
2412              //Build the classanalysiswrapper referring to the previous array
2413              output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
2414              output.println("/*type*/"+cdtemp.getId()+",");
2415              output.println("/*numotd*/"+numotd+",");
2416              output.println("otdarray"+cdtemp.getSafeSymbol()+",");
2417              output.println("/* number of fsanalysiswrappers */"+fscounter+",");
2418              output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
2419              fscounter = 0;
2420              processedcd.add(cdtemp);
2421          }
2422          
2423          //build an array containing every classes for which code has been build
2424          output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
2425          boolean needcomma=false;
2426          for(Iterator classit = processedcd.iterator(); classit.hasNext();){
2427              ClassDescriptor cdtemp=(ClassDescriptor)classit.next();
2428              if (needcomma)
2429                  output.println(", ");
2430              needcomma=true;
2431              output.println("&classanalysiswrapper_"+cdtemp.getSafeSymbol());
2432          }
2433          output.println("};");
2434          
2435          output.println("int numclasses="+processedcd.size()+";");
2436          headers.println("extern numclasses;");
2437          output.println("int maxotd="+maxotd+";");
2438          headers.println("extern maxotd;");
2439          headers.println("#endif");
2440         
2441          
2442      }
2443     
2444 }
2445          
2446
2447
2448
2449
2450