updates on Math operations for multicore version
[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.Tree.OffsetNode;
7 import IR.*;
8 import java.util.*;
9 import java.io.*;
10
11 import Util.Relation;
12 import Analysis.TaskStateAnalysis.FlagState;
13 import Analysis.TaskStateAnalysis.FlagComparator;
14 import Analysis.TaskStateAnalysis.OptionalTaskDescriptor;
15 import Analysis.TaskStateAnalysis.Predicate;
16 import Analysis.TaskStateAnalysis.SafetyAnalysis;
17 import Analysis.TaskStateAnalysis.TaskIndex;
18 import Analysis.Locality.LocalityAnalysis;
19 import Analysis.Locality.LocalityBinding;
20 import Analysis.Locality.DiscoverConflicts;
21 import Analysis.CallGraph.CallGraph;
22 import Analysis.Prefetch.*;
23 import Analysis.Loops.WriteBarrier;
24 import Analysis.Locality.TypeAnalysis;
25
26 public class BuildCode {
27   State state;
28   Hashtable temptovar;
29   Hashtable paramstable;
30   Hashtable tempstable;
31   Hashtable fieldorder;
32   Hashtable flagorder;
33   int tag=0;
34   String localsprefix="___locals___";
35   String fcrevert="___fcrevert___";
36   String paramsprefix="___params___";
37   String oidstr="___nextobject___";
38   String nextobjstr="___nextobject___";
39   String localcopystr="___localcopy___";
40   public static boolean GENERATEPRECISEGC=false;
41   public static String PREFIX="";
42   public static String arraytype="ArrayObject";
43   public static int flagcount = 0;
44   Virtual virtualcalls;
45   TypeUtil typeutil;
46   protected int maxtaskparams=0;
47   private int maxcount=0;
48   ClassDescriptor[] cdarray;
49   TypeDescriptor[] arraytable;
50   LocalityAnalysis locality;
51   Hashtable<LocalityBinding, TempDescriptor> reverttable;
52   Hashtable<LocalityBinding, Hashtable<TempDescriptor, TempDescriptor>> backuptable;
53   SafetyAnalysis sa;
54   PrefetchAnalysis pa;
55   HashSet<FlatSESEEnterNode> setSESEtoGen;
56   boolean nonSESEpass=true;
57   WriteBarrier wb;
58   DiscoverConflicts dc;
59   CallGraph callgraph;
60
61   public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, SafetyAnalysis sa, PrefetchAnalysis pa) {
62     this(st, temptovar, typeutil, null, sa, pa);
63   }
64
65   public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, PrefetchAnalysis pa) {
66     this(st, temptovar, typeutil, locality, null, pa);
67   }
68
69   public BuildCode(State st, Hashtable temptovar, TypeUtil typeutil, LocalityAnalysis locality, SafetyAnalysis sa, PrefetchAnalysis pa) {
70     this.sa=sa;
71     this.pa=pa;
72     state=st;
73     callgraph=new CallGraph(state);
74     if (state.SINGLETM)
75       oidstr="___objlocation___";
76     this.temptovar=temptovar;
77     paramstable=new Hashtable();
78     tempstable=new Hashtable();
79     fieldorder=new Hashtable();
80     flagorder=new Hashtable();
81     this.typeutil=typeutil;
82     virtualcalls=new Virtual(state,locality);
83     if (locality!=null) {
84       this.locality=locality;
85       this.reverttable=new Hashtable<LocalityBinding, TempDescriptor>();
86       this.backuptable=new Hashtable<LocalityBinding, Hashtable<TempDescriptor, TempDescriptor>>();
87       this.wb=new WriteBarrier(locality, st);
88     }
89     if (state.SINGLETM&&state.DCOPTS) {
90       TypeAnalysis typeanalysis=new TypeAnalysis(locality, st, typeutil,callgraph);
91       this.dc=new DiscoverConflicts(locality, st, typeanalysis);
92       dc.doAnalysis();
93     }
94
95     setSESEtoGen = new HashSet<FlatSESEEnterNode>();
96   }
97
98   /** The buildCode method outputs C code for all the methods.  The Flat
99    * versions of the methods must already be generated and stored in
100    * the State object. */
101
102   public void buildCode() {
103     /* Create output streams to write to */
104     PrintWriter outclassdefs=null;
105     PrintWriter outstructs=null;
106     PrintWriter outrepairstructs=null;
107     PrintWriter outmethodheader=null;
108     PrintWriter outmethod=null;
109     PrintWriter outvirtual=null;
110     PrintWriter outtask=null;
111     PrintWriter outtaskdefs=null;
112     PrintWriter outoptionalarrays=null;
113     PrintWriter optionalheaders=null;
114
115     try {
116       outstructs=new PrintWriter(new FileOutputStream(PREFIX+"structdefs.h"), true);
117       outmethodheader=new PrintWriter(new FileOutputStream(PREFIX+"methodheaders.h"), true);
118       outclassdefs=new PrintWriter(new FileOutputStream(PREFIX+"classdefs.h"), true);
119       outmethod=new PrintWriter(new FileOutputStream(PREFIX+"methods.c"), true);
120       outvirtual=new PrintWriter(new FileOutputStream(PREFIX+"virtualtable.h"), true);
121       if (state.TASK) {
122         outtask=new PrintWriter(new FileOutputStream(PREFIX+"task.h"), true);
123         outtaskdefs=new PrintWriter(new FileOutputStream(PREFIX+"taskdefs.c"), true);
124         if (state.OPTIONAL) {
125           outoptionalarrays=new PrintWriter(new FileOutputStream(PREFIX+"optionalarrays.c"), true);
126           optionalheaders=new PrintWriter(new FileOutputStream(PREFIX+"optionalstruct.h"), true);
127         }
128       }
129       if (state.structfile!=null) {
130         outrepairstructs=new PrintWriter(new FileOutputStream(PREFIX+state.structfile+".struct"), true);
131       }
132     } catch (Exception e) {
133       e.printStackTrace();
134       System.exit(-1);
135     }
136
137     /* Build the virtual dispatch tables */
138     buildVirtualTables(outvirtual);
139
140     /* Output includes */
141     outmethodheader.println("#ifndef METHODHEADERS_H");
142     outmethodheader.println("#define METHODHEADERS_H");
143     outmethodheader.println("#include \"structdefs.h\"");
144     if (state.DSM)
145       outmethodheader.println("#include \"dstm.h\"");
146     if (state.SINGLETM)
147       outmethodheader.println("#include \"tm.h\"");
148     if (state.ABORTREADERS) {
149       outmethodheader.println("#include \"abortreaders.h\"");
150       outmethodheader.println("#include <setjmp.h>");
151     }
152
153     /* Output Structures */
154     outputStructs(outstructs);
155
156     // Output the C class declarations
157     // These could mutually reference each other
158     outputClassDeclarations(outclassdefs);
159
160     // Output function prototypes and structures for parameters
161     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
162     while(it.hasNext()) {
163       ClassDescriptor cn=(ClassDescriptor)it.next();
164       generateCallStructs(cn, outclassdefs, outstructs, outmethodheader);
165     }
166     outclassdefs.close();
167
168     if (state.TASK) {
169       /* Map flags to integers */
170       /* The runtime keeps track of flags using these integers */
171       it=state.getClassSymbolTable().getDescriptorsIterator();
172       while(it.hasNext()) {
173         ClassDescriptor cn=(ClassDescriptor)it.next();
174         mapFlags(cn);
175       }
176       /* Generate Tasks */
177       generateTaskStructs(outstructs, outmethodheader);
178
179       /* Outputs generic task structures if this is a task
180          program */
181       outputTaskTypes(outtask);
182     }
183
184     /* Build the actual methods */
185     outputMethods(outmethod);
186
187     if( state.MLP ) {
188       nonSESEpass = false;
189       while( !setSESEtoGen.isEmpty() ) {
190         FlatSESEEnterNode fsen = setSESEtoGen.iterator().next();
191         setSESEtoGen.remove(fsen);
192         generateMethodSESE(fsen, fsen.getEnclosingFlatMeth(), null, outmethod);
193       }
194     } else {
195       assert setSESEtoGen.isEmpty();
196     }
197
198     if (state.TASK) {
199       /* Output code for tasks */
200       outputTaskCode(outtaskdefs, outmethod);
201       outtaskdefs.close();
202       /* Record maximum number of task parameters */
203       outstructs.println("#define MAXTASKPARAMS "+maxtaskparams);
204     } else if (state.main!=null) {
205       /* Generate main method */
206       outputMainMethod(outmethod);
207     }
208
209     /* Generate information for task with optional parameters */
210     if (state.TASK&&state.OPTIONAL) {
211       generateOptionalArrays(outoptionalarrays, optionalheaders, state.getAnalysisResult(), state.getOptionalTaskDescriptors());
212       outoptionalarrays.close();
213     }
214
215     /* Output structure definitions for repair tool */
216     if (state.structfile!=null) {
217       buildRepairStructs(outrepairstructs);
218       outrepairstructs.close();
219     }
220
221     /* Close files */
222     outmethodheader.println("#endif");
223     outmethodheader.close();
224     outmethod.close();
225     outstructs.println("#endif");
226     outstructs.close();
227   }
228
229
230   /* This code just generates the main C method for java programs.
231    * The main C method packs up the arguments into a string array
232    * and passes it to the java main method. */
233
234   private void outputMainMethod(PrintWriter outmethod) {
235     outmethod.println("int main(int argc, const char *argv[]) {");
236     outmethod.println("  int i;");
237     if (state.DSM) {
238       outmethod.println("#ifdef TRANSSTATS \n");
239       outmethod.println("handle();\n");
240       outmethod.println("#endif\n");
241     }
242     if (state.THREAD||state.DSM||state.SINGLETM) {
243       outmethod.println("initializethreads();");
244       outmethod.println("#ifdef STMSTATS\n");
245       outmethod.println(" for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {");
246       outmethod.println("   typesCausingAbort[i] = 0;");
247       outmethod.println(" }");
248       outmethod.println("#endif\n");
249     }
250     if (state.DSM) {
251       outmethod.println("if (dstmStartup(argv[1])) {");
252       if (GENERATEPRECISEGC) {
253         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-2);");
254       } else {
255         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-2);");
256       }
257     } else {
258       if (GENERATEPRECISEGC) {
259         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);");
260       } else {
261         outmethod.println("  struct ArrayObject * stringarray=allocate_newarray(STRINGARRAYTYPE, argc-1);");
262       }
263     }
264     if (state.DSM) {
265       outmethod.println("  for(i=2;i<argc;i++) {");
266     } else
267       outmethod.println("  for(i=1;i<argc;i++) {");
268     outmethod.println("    int length=strlen(argv[i]);");
269     if (GENERATEPRECISEGC) {
270       outmethod.println("    struct ___String___ *newstring=NewString(NULL, argv[i], length);");
271     } else {
272       outmethod.println("    struct ___String___ *newstring=NewString(argv[i], length);");
273     }
274     if (state.DSM)
275       outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-2]=newstring;");
276     else
277       outmethod.println("    ((void **)(((char *)& stringarray->___length___)+sizeof(int)))[i-1]=newstring;");
278     outmethod.println("  }");
279
280
281     MethodDescriptor md=typeutil.getMain();
282     ClassDescriptor cd=typeutil.getMainClass();
283
284     outmethod.println("   {");
285     if (GENERATEPRECISEGC) {
286       if (state.DSM||state.SINGLETM) {
287         outmethod.print("       struct "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
288       } else
289         outmethod.print("       struct "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
290       outmethod.println("1, NULL,"+"stringarray};");
291       if (state.DSM||state.SINGLETM)
292         outmethod.println("     "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
293       else
294         outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(& __parameterlist__);");
295     } else {
296       if (state.DSM||state.SINGLETM)
297         outmethod.println("     "+cd.getSafeSymbol()+locality.getMain().getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
298       else
299         outmethod.println("     "+cd.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(stringarray);");
300     }
301     outmethod.println("   }");
302
303     if (state.DSM) {
304       outmethod.println("}");
305     }
306
307     if (state.THREAD||state.DSM||state.SINGLETM) {
308       outmethod.println("pthread_mutex_lock(&gclistlock);");
309       outmethod.println("threadcount--;");
310       outmethod.println("pthread_cond_signal(&gccond);");
311       outmethod.println("pthread_mutex_unlock(&gclistlock);");
312     }
313
314     if (state.DSM||state.SINGLETM) {
315       outmethod.println("#ifdef TRANSSTATS \n");
316       outmethod.println("printf(\"******  Transaction Stats   ******\\n\");");
317       outmethod.println("printf(\"numTransAbort= %d\\n\", numTransAbort);");
318       outmethod.println("printf(\"numTransCommit= %d\\n\", numTransCommit);");
319       outmethod.println("printf(\"nSoftAbort= %d\\n\", nSoftAbort);");
320       if (state.DSM) {
321         outmethod.println("printf(\"nchashSearch= %d\\n\", nchashSearch);");
322         outmethod.println("printf(\"nmhashSearch= %d\\n\", nmhashSearch);");
323         outmethod.println("printf(\"nprehashSearch= %d\\n\", nprehashSearch);");
324         outmethod.println("printf(\"nRemoteReadSend= %d\\n\", nRemoteSend);");
325         outmethod.println("printf(\"bytesSent= %d\\n\", bytesSent);");
326         outmethod.println("printf(\"bytesRecv= %d\\n\", bytesRecv);");
327       } else if (state.SINGLETM) {
328         outmethod.println("printf(\"nSoftAbortAbort= %d\\n\", nSoftAbortAbort);");
329         outmethod.println("printf(\"nSoftAbortCommit= %d\\n\", nSoftAbortCommit);");
330         outmethod.println("#ifdef STMSTATS\n");
331         outmethod.println("for(i=0; i<TOTALNUMCLASSANDARRAY; i++) {\n");
332         outmethod.println("  printf(\"typesCausingAbort[%d]= %d\\n\", i, typesCausingAbort[i]);\n");
333         outmethod.println("}\n");
334         outmethod.println("#endif\n");
335         outmethod.println("fflush(stdout);");
336       }
337       outmethod.println("#endif\n");
338     }
339
340     if (state.THREAD||state.SINGLETM)
341       outmethod.println("pthread_exit(NULL);");
342
343     outmethod.println("}");
344
345   }
346
347   /* This method outputs code for each task. */
348
349   private void outputTaskCode(PrintWriter outtaskdefs, PrintWriter outmethod) {
350     /* Compile task based program */
351     outtaskdefs.println("#include \"task.h\"");
352     outtaskdefs.println("#include \"methodheaders.h\"");
353     Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
354     while(taskit.hasNext()) {
355       TaskDescriptor td=(TaskDescriptor)taskit.next();
356       FlatMethod fm=state.getMethodFlat(td);
357       generateFlatMethod(fm, null, outmethod);
358       generateTaskDescriptor(outtaskdefs, fm, td);
359     }
360
361     //Output task descriptors
362     taskit=state.getTaskSymbolTable().getDescriptorsIterator();
363     outtaskdefs.println("struct taskdescriptor * taskarray[]= {");
364     boolean first=true;
365     while(taskit.hasNext()) {
366       TaskDescriptor td=(TaskDescriptor)taskit.next();
367       if (first)
368         first=false;
369       else
370         outtaskdefs.println(",");
371       outtaskdefs.print("&task_"+td.getSafeSymbol());
372     }
373     outtaskdefs.println("};");
374
375     outtaskdefs.println("int numtasks="+state.getTaskSymbolTable().getValueSet().size()+";");
376   }
377
378   /* This method outputs most of the methods.c file.  This includes
379    * some standard includes and then an array with the sizes of
380    * objets and array that stores supertype and then the code for
381    * the Java methods.. */
382
383   protected void outputMethods(PrintWriter outmethod) {
384     outmethod.println("#include \"methodheaders.h\"");
385     outmethod.println("#include \"virtualtable.h\"");
386     outmethod.println("#include \"runtime.h\"");
387     if (state.DSM) {
388       outmethod.println("#include \"addPrefetchEnhance.h\"");
389       outmethod.println("#include \"localobjects.h\"");
390     }
391     if (state.FASTCHECK) {
392       outmethod.println("#include \"localobjects.h\"");
393     }
394     if(state.MULTICORE) {
395       outmethod.println("#include \"task.h\"");
396           outmethod.println("#include \"multicoreruntime.h\"");
397           outmethod.println("#include \"runtime_arch.h\"");
398     }
399     if (state.THREAD||state.DSM||state.SINGLETM)
400       outmethod.println("#include <thread.h>");
401     if (state.main!=null) {
402       outmethod.println("#include <string.h>");
403     }
404     if (state.CONSCHECK) {
405       outmethod.println("#include \"checkers.h\"");
406     }
407     if (state.MLP) {
408       outmethod.println("#include \"mlp_runtime.h\"");
409     }
410
411     //Store the sizes of classes & array elements
412     generateSizeArray(outmethod);
413
414     //Store table of supertypes
415     generateSuperTypeTable(outmethod);
416
417     //Store the layout of classes
418     generateLayoutStructs(outmethod);
419
420     /* Generate code for methods */
421     if (state.DSM||state.SINGLETM) {
422       for(Iterator<LocalityBinding> lbit=locality.getLocalityBindings().iterator(); lbit.hasNext();) {
423         LocalityBinding lb=lbit.next();
424         MethodDescriptor md=lb.getMethod();
425         FlatMethod fm=state.getMethodFlat(md);
426         wb.analyze(lb);
427         if (!md.getModifiers().isNative()) {
428           generateFlatMethod(fm, lb, outmethod);
429         }
430       }
431     } else {
432       Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
433       while(classit.hasNext()) {
434         ClassDescriptor cn=(ClassDescriptor)classit.next();
435         if(state.MULTICORE) {
436                 if(cn.getSymbol().equals("Math")) {
437                         continue;
438                 }
439         }
440         Iterator methodit=cn.getMethods();
441         while(methodit.hasNext()) {
442           /* Classify parameters */
443           MethodDescriptor md=(MethodDescriptor)methodit.next();
444           FlatMethod fm=state.getMethodFlat(md);
445           if (!md.getModifiers().isNative()) {
446             generateFlatMethod(fm, null, outmethod);
447           }
448         }
449       }
450     }
451   }
452
453   protected void outputStructs(PrintWriter outstructs) {
454     outstructs.println("#ifndef STRUCTDEFS_H");
455     outstructs.println("#define STRUCTDEFS_H");
456     outstructs.println("#include \"classdefs.h\"");
457     outstructs.println("#ifndef INTPTR");
458     outstructs.println("#ifdef BIT64");
459     outstructs.println("#define INTPTR long");
460     outstructs.println("#else");
461     outstructs.println("#define INTPTR int");
462     outstructs.println("#endif");
463     outstructs.println("#endif");
464
465     /* Output #defines that the runtime uses to determine type
466      * numbers for various objects it needs */
467     outstructs.println("#define MAXCOUNT "+maxcount);
468     if (state.DSM||state.SINGLETM) {
469       LocalityBinding lb=new LocalityBinding(typeutil.getRun(), false);
470       if (state.DSM)
471         lb.setGlobalThis(LocalityAnalysis.GLOBAL);
472       else if (state.SINGLETM)
473         lb.setGlobalThis(LocalityAnalysis.NORMAL);
474       outstructs.println("#define RUNMETHOD "+virtualcalls.getLocalityNumber(lb));
475     }
476
477     outstructs.println("#define STRINGARRAYTYPE "+
478                        (state.getArrayNumber(
479                           (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses()));
480
481     outstructs.println("#define OBJECTARRAYTYPE "+
482                        (state.getArrayNumber(
483                           (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses()));
484
485
486     outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId());
487     outstructs.println("#define CHARARRAYTYPE "+
488                        (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses()));
489
490     outstructs.println("#define BYTEARRAYTYPE "+
491                        (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state))+state.numClasses()));
492
493     outstructs.println("#define BYTEARRAYARRAYTYPE "+
494                        (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses()));
495
496     outstructs.println("#define NUMCLASSES "+state.numClasses());
497     int totalClassSize = state.numClasses() + state.numArrays();
498     outstructs.println("#define TOTALNUMCLASSANDARRAY "+ totalClassSize);
499     if (state.TASK) {
500       outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId());
501       outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId());
502       outstructs.println("#define TAGARRAYTYPE "+
503                          (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses()));
504     }
505   }
506
507   protected void outputClassDeclarations(PrintWriter outclassdefs) {
508     if (state.THREAD||state.DSM||state.SINGLETM)
509       outclassdefs.println("#include <pthread.h>");
510     outclassdefs.println("#ifndef INTPTR");
511     outclassdefs.println("#ifdef BIT64");
512     outclassdefs.println("#define INTPTR long");
513     outclassdefs.println("#else");
514     outclassdefs.println("#define INTPTR int");
515     outclassdefs.println("#endif");
516     outclassdefs.println("#endif");
517     if(state.OPTIONAL)
518       outclassdefs.println("#include \"optionalstruct.h\"");
519     outclassdefs.println("struct "+arraytype+";");
520     /* Start by declaring all structs */
521     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
522     while(it.hasNext()) {
523       ClassDescriptor cn=(ClassDescriptor)it.next();
524       outclassdefs.println("struct "+cn.getSafeSymbol()+";");
525     }
526     outclassdefs.println("");
527     //Print out definition for array type
528     outclassdefs.println("struct "+arraytype+" {");
529     outclassdefs.println("  int type;");
530     if (state.THREAD) {
531       outclassdefs.println("  pthread_t tid;");
532       outclassdefs.println("  void * lockentry;");
533       outclassdefs.println("  int lockcount;");
534     }
535     if (state.TASK) {
536       outclassdefs.println("  int flag;");
537       if(!state.MULTICORE) {
538         outclassdefs.println("  void * flagptr;");
539       } else {
540         outclassdefs.println("  int isolate;");        // indicate if this object is shared or not
541         outclassdefs.println("  int version;");
542         outclassdefs.println("  struct ___Object___ * original;");
543         //outclassdefs.println("  int numlocks;");        // array for locks
544         outclassdefs.println("  int * lock;");
545       }
546       if(state.OPTIONAL) {
547         outclassdefs.println("  int numfses;");
548         outclassdefs.println("  int * fses;");
549       }
550     }
551     printClassStruct(typeutil.getClass(TypeUtil.ObjectClass), outclassdefs);
552
553     outclassdefs.println("  int ___length___;");
554     outclassdefs.println("};\n");
555     outclassdefs.println("extern int classsize[];");
556     outclassdefs.println("extern int hasflags[];");
557     outclassdefs.println("extern unsigned INTPTR * pointerarray[];");
558     outclassdefs.println("extern int supertypes[];");
559   }
560
561   /** Prints out definitions for generic task structures */
562
563   private void outputTaskTypes(PrintWriter outtask) {
564     outtask.println("#ifndef _TASK_H");
565     outtask.println("#define _TASK_H");
566     outtask.println("struct parameterdescriptor {");
567     outtask.println("int type;");
568     outtask.println("int numberterms;");
569     outtask.println("int *intarray;");
570     outtask.println("void * queue;");
571     outtask.println("int numbertags;");
572     outtask.println("int *tagarray;");
573     outtask.println("};");
574
575     outtask.println("struct taskdescriptor {");
576     outtask.println("void * taskptr;");
577     outtask.println("int numParameters;");
578     outtask.println("  int numTotal;");
579     outtask.println("struct parameterdescriptor **descriptorarray;");
580     outtask.println("char * name;");
581     outtask.println("};");
582     outtask.println("extern struct taskdescriptor * taskarray[];");
583     outtask.println("extern numtasks;");
584     outtask.println("#endif");
585   }
586
587
588   private void buildRepairStructs(PrintWriter outrepairstructs) {
589     Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
590     while(classit.hasNext()) {
591       ClassDescriptor cn=(ClassDescriptor)classit.next();
592       outrepairstructs.println("structure "+cn.getSymbol()+" {");
593       outrepairstructs.println("  int __type__;");
594       if (state.TASK) {
595         outrepairstructs.println("  int __flag__;");
596         if(!state.MULTICORE) {
597           outrepairstructs.println("  int __flagptr__;");
598         }
599       }
600       printRepairStruct(cn, outrepairstructs);
601       outrepairstructs.println("}\n");
602     }
603
604     for(int i=0; i<state.numArrays(); i++) {
605       TypeDescriptor tdarray=arraytable[i];
606       TypeDescriptor tdelement=tdarray.dereference();
607       outrepairstructs.println("structure "+arraytype+"_"+state.getArrayNumber(tdarray)+" {");
608       outrepairstructs.println("  int __type__;");
609       printRepairStruct(typeutil.getClass(TypeUtil.ObjectClass), outrepairstructs);
610       outrepairstructs.println("  int length;");
611       /*
612          // Need to add support to repair tool for this
613          if (tdelement.isClass()||tdelement.isArray())
614           outrepairstructs.println("  "+tdelement.getRepairSymbol()+" * elem[this.length];");
615          else
616           outrepairstructs.println("  "+tdelement.getRepairSymbol()+" elem[this.length];");
617        */
618       outrepairstructs.println("}\n");
619     }
620   }
621
622   private void printRepairStruct(ClassDescriptor cn, PrintWriter output) {
623     ClassDescriptor sp=cn.getSuperDesc();
624     if (sp!=null)
625       printRepairStruct(sp, output);
626
627     Vector fields=(Vector)fieldorder.get(cn);
628
629     for(int i=0; i<fields.size(); i++) {
630       FieldDescriptor fd=(FieldDescriptor)fields.get(i);
631       if (fd.getType().isArray()) {
632         output.println("  "+arraytype+"_"+ state.getArrayNumber(fd.getType()) +" * "+fd.getSymbol()+";");
633       } else if (fd.getType().isClass())
634         output.println("  "+fd.getType().getRepairSymbol()+" * "+fd.getSymbol()+";");
635       else if (fd.getType().isFloat())
636         output.println("  int "+fd.getSymbol()+"; /* really float */");
637       else
638         output.println("  "+fd.getType().getRepairSymbol()+" "+fd.getSymbol()+";");
639     }
640   }
641
642   /** This method outputs TaskDescriptor information */
643   private void generateTaskDescriptor(PrintWriter output, FlatMethod fm, TaskDescriptor task) {
644     for (int i=0; i<task.numParameters(); i++) {
645       VarDescriptor param_var=task.getParameter(i);
646       TypeDescriptor param_type=task.getParamType(i);
647       FlagExpressionNode param_flag=task.getFlag(param_var);
648       TagExpressionList param_tag=task.getTag(param_var);
649
650       int dnfterms;
651       if (param_flag==null) {
652         output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
653         output.println("0x0, 0x0 };");
654         dnfterms=1;
655       } else {
656         DNFFlag dflag=param_flag.getDNF();
657         dnfterms=dflag.size();
658
659         Hashtable flags=(Hashtable)flagorder.get(param_type.getClassDesc());
660         output.println("int parameterdnf_"+i+"_"+task.getSafeSymbol()+"[]={");
661         for(int j=0; j<dflag.size(); j++) {
662           if (j!=0)
663             output.println(",");
664           Vector term=dflag.get(j);
665           int andmask=0;
666           int checkmask=0;
667           for(int k=0; k<term.size(); k++) {
668             DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
669             FlagDescriptor fd=dfa.getFlag();
670             boolean negated=dfa.getNegated();
671             int flagid=1<<((Integer)flags.get(fd)).intValue();
672             andmask|=flagid;
673             if (!negated)
674               checkmask|=flagid;
675           }
676           output.print("0x"+Integer.toHexString(andmask)+", 0x"+Integer.toHexString(checkmask));
677         }
678         output.println("};");
679       }
680
681       output.println("int parametertag_"+i+"_"+task.getSafeSymbol()+"[]={");
682       //BUG...added next line to fix, test with any task program
683       if (param_tag!=null)
684         for(int j=0; j<param_tag.numTags(); j++) {
685           if (j!=0)
686             output.println(",");
687           /* for each tag we need */
688           /* which slot it is */
689           /* what type it is */
690           TagVarDescriptor tvd=(TagVarDescriptor)task.getParameterTable().get(param_tag.getName(j));
691           TempDescriptor tmp=param_tag.getTemp(j);
692           int slot=fm.getTagInt(tmp);
693           output.println(slot+", "+state.getTagId(tvd.getTag()));
694         }
695       output.println("};");
696
697       output.println("struct parameterdescriptor parameter_"+i+"_"+task.getSafeSymbol()+"={");
698       output.println("/* type */"+param_type.getClassDesc().getId()+",");
699       output.println("/* number of DNF terms */"+dnfterms+",");
700       output.println("parameterdnf_"+i+"_"+task.getSafeSymbol()+",");
701       output.println("0,");
702       //BUG, added next line to fix and else statement...test
703       //with any task program
704       if (param_tag!=null)
705         output.println("/* number of tags */"+param_tag.numTags()+",");
706       else
707         output.println("/* number of tags */ 0,");
708       output.println("parametertag_"+i+"_"+task.getSafeSymbol());
709       output.println("};");
710     }
711
712
713     output.println("struct parameterdescriptor * parameterdescriptors_"+task.getSafeSymbol()+"[] = {");
714     for (int i=0; i<task.numParameters(); i++) {
715       if (i!=0)
716         output.println(",");
717       output.print("&parameter_"+i+"_"+task.getSafeSymbol());
718     }
719     output.println("};");
720
721     output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={");
722     output.println("&"+task.getSafeSymbol()+",");
723     output.println("/* number of parameters */" +task.numParameters() + ",");
724     int numtotal=task.numParameters()+fm.numTags();
725     output.println("/* number total parameters */" +numtotal + ",");
726     output.println("parameterdescriptors_"+task.getSafeSymbol()+",");
727     output.println("\""+task.getSymbol()+"\"");
728     output.println("};");
729   }
730
731
732   /** The buildVirtualTables method outputs the virtual dispatch
733    * tables for methods. */
734
735   protected void buildVirtualTables(PrintWriter outvirtual) {
736     Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
737     while(classit.hasNext()) {
738       ClassDescriptor cd=(ClassDescriptor)classit.next();
739       if (virtualcalls.getMethodCount(cd)>maxcount)
740         maxcount=virtualcalls.getMethodCount(cd);
741     }
742     MethodDescriptor[][] virtualtable=null;
743     LocalityBinding[][] lbvirtualtable=null;
744     if (state.DSM||state.SINGLETM)
745       lbvirtualtable=new LocalityBinding[state.numClasses()+state.numArrays()][maxcount];
746     else
747       virtualtable=new MethodDescriptor[state.numClasses()+state.numArrays()][maxcount];
748
749     /* Fill in virtual table */
750     classit=state.getClassSymbolTable().getDescriptorsIterator();
751     while(classit.hasNext()) {
752       ClassDescriptor cd=(ClassDescriptor)classit.next();
753       if (state.DSM||state.SINGLETM)
754         fillinRow(cd, lbvirtualtable, cd.getId());
755       else
756         fillinRow(cd, virtualtable, cd.getId());
757     }
758
759     ClassDescriptor objectcd=typeutil.getClass(TypeUtil.ObjectClass);
760     Iterator arrayit=state.getArrayIterator();
761     while(arrayit.hasNext()) {
762       TypeDescriptor td=(TypeDescriptor)arrayit.next();
763       int id=state.getArrayNumber(td);
764       if (state.DSM||state.SINGLETM)
765         fillinRow(objectcd, lbvirtualtable, id+state.numClasses());
766       else
767         fillinRow(objectcd, virtualtable, id+state.numClasses());
768     }
769
770     outvirtual.print("void * virtualtable[]={");
771     boolean needcomma=false;
772     for(int i=0; i<state.numClasses()+state.numArrays(); i++) {
773       for(int j=0; j<maxcount; j++) {
774         if (needcomma)
775           outvirtual.print(", ");
776         if ((state.DSM||state.SINGLETM)&&lbvirtualtable[i][j]!=null) {
777           LocalityBinding lb=lbvirtualtable[i][j];
778           MethodDescriptor md=lb.getMethod();
779           outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
780         } else if (!(state.DSM||state.SINGLETM)&&virtualtable[i][j]!=null) {
781           MethodDescriptor md=virtualtable[i][j];
782           outvirtual.print("& "+md.getClassDesc().getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
783         } else {
784           outvirtual.print("0");
785         }
786         needcomma=true;
787       }
788       outvirtual.println("");
789     }
790     outvirtual.println("};");
791     outvirtual.close();
792   }
793
794   private void fillinRow(ClassDescriptor cd, MethodDescriptor[][] virtualtable, int rownum) {
795     /* Get inherited methods */
796     if (cd.getSuperDesc()!=null)
797       fillinRow(cd.getSuperDesc(), virtualtable, rownum);
798     /* Override them with our methods */
799     for(Iterator it=cd.getMethods(); it.hasNext();) {
800       MethodDescriptor md=(MethodDescriptor)it.next();
801       if (md.isStatic()||md.getReturnType()==null)
802         continue;
803       int methodnum=virtualcalls.getMethodNumber(md);
804       virtualtable[rownum][methodnum]=md;
805     }
806   }
807
808   private void fillinRow(ClassDescriptor cd, LocalityBinding[][] virtualtable, int rownum) {
809     /* Get inherited methods */
810     if (cd.getSuperDesc()!=null)
811       fillinRow(cd.getSuperDesc(), virtualtable, rownum);
812     /* Override them with our methods */
813     if (locality.getClassBindings(cd)!=null)
814       for(Iterator<LocalityBinding> lbit=locality.getClassBindings(cd).iterator(); lbit.hasNext();) {
815         LocalityBinding lb=lbit.next();
816         MethodDescriptor md=lb.getMethod();
817         //Is the method static or a constructor
818         if (md.isStatic()||md.getReturnType()==null)
819           continue;
820         int methodnum=virtualcalls.getLocalityNumber(lb);
821         virtualtable[rownum][methodnum]=lb;
822       }
823   }
824
825   /** Generate array that contains the sizes of class objects.  The
826    * object allocation functions in the runtime use this
827    * information. */
828
829   private void generateSizeArray(PrintWriter outclassdefs) {
830     outclassdefs.print("extern struct prefetchCountStats * evalPrefetch;\n");
831     outclassdefs.print("#ifdef TRANSSTATS \n");
832     outclassdefs.print("extern int numTransAbort;\n");
833     outclassdefs.print("extern int numTransCommit;\n");
834     outclassdefs.print("extern int nSoftAbort;\n");
835     if (state.DSM) {
836       outclassdefs.print("extern int nchashSearch;\n");
837       outclassdefs.print("extern int nmhashSearch;\n");
838       outclassdefs.print("extern int nprehashSearch;\n");
839       outclassdefs.print("extern int nRemoteSend;\n");
840       outclassdefs.print("extern int bytesSent;\n");
841       outclassdefs.print("extern int bytesRecv;\n");
842       outclassdefs.print("extern void handle();\n");
843     } else if (state.SINGLETM) {
844       outclassdefs.println("extern int nSoftAbortAbort;");
845       outclassdefs.println("extern int nSoftAbortCommit;");
846       outclassdefs.println("#ifdef STMSTATS\n");
847       outclassdefs.println("extern int typesCausingAbort[];");
848       outclassdefs.println("#endif\n");
849     }
850     outclassdefs.print("#endif\n");
851     outclassdefs.print("int numprefetchsites = " + pa.prefetchsiteid + ";\n");
852
853     outclassdefs.print("int classsize[]={");
854     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
855     cdarray=new ClassDescriptor[state.numClasses()];
856     while(it.hasNext()) {
857       ClassDescriptor cd=(ClassDescriptor)it.next();
858       cdarray[cd.getId()]=cd;
859     }
860     boolean needcomma=false;
861     for(int i=0; i<state.numClasses(); i++) {
862       if (needcomma)
863         outclassdefs.print(", ");
864       outclassdefs.print("sizeof(struct "+cdarray[i].getSafeSymbol()+")");
865       needcomma=true;
866     }
867
868
869     arraytable=new TypeDescriptor[state.numArrays()];
870
871     Iterator arrayit=state.getArrayIterator();
872     while(arrayit.hasNext()) {
873       TypeDescriptor td=(TypeDescriptor)arrayit.next();
874       int id=state.getArrayNumber(td);
875       arraytable[id]=td;
876     }
877
878     for(int i=0; i<state.numArrays(); i++) {
879       if (needcomma)
880         outclassdefs.print(", ");
881       TypeDescriptor tdelement=arraytable[i].dereference();
882       if (tdelement.isArray()||tdelement.isClass())
883         outclassdefs.print("sizeof(void *)");
884       else
885         outclassdefs.print("sizeof("+tdelement.getSafeSymbol()+")");
886       needcomma=true;
887     }
888
889     outclassdefs.println("};");
890
891     ClassDescriptor objectclass=typeutil.getClass(TypeUtil.ObjectClass);
892     needcomma=false;
893     outclassdefs.print("int typearray[]={");
894     for(int i=0; i<state.numClasses(); i++) {
895       ClassDescriptor cd=cdarray[i];
896       ClassDescriptor supercd=cd.getSuperDesc();
897       if (needcomma)
898         outclassdefs.print(", ");
899       if (supercd==null)
900         outclassdefs.print("-1");
901       else
902         outclassdefs.print(supercd.getId());
903       needcomma=true;
904     }
905
906     for(int i=0; i<state.numArrays(); i++) {
907       TypeDescriptor arraytd=arraytable[i];
908       ClassDescriptor arraycd=arraytd.getClassDesc();
909       if (arraycd==null) {
910         if (needcomma)
911           outclassdefs.print(", ");
912         outclassdefs.print(objectclass.getId());
913         needcomma=true;
914         continue;
915       }
916       ClassDescriptor cd=arraycd.getSuperDesc();
917       int type=-1;
918       while(cd!=null) {
919         TypeDescriptor supertd=new TypeDescriptor(cd);
920         supertd.setArrayCount(arraytd.getArrayCount());
921         type=state.getArrayNumber(supertd);
922         if (type!=-1) {
923           type+=state.numClasses();
924           break;
925         }
926         cd=cd.getSuperDesc();
927       }
928       if (needcomma)
929         outclassdefs.print(", ");
930       outclassdefs.print(type);
931       needcomma=true;
932     }
933
934     outclassdefs.println("};");
935
936     needcomma=false;
937
938
939     outclassdefs.print("int typearray2[]={");
940     for(int i=0; i<state.numArrays(); i++) {
941       TypeDescriptor arraytd=arraytable[i];
942       ClassDescriptor arraycd=arraytd.getClassDesc();
943       if (arraycd==null) {
944         if (needcomma)
945           outclassdefs.print(", ");
946         outclassdefs.print("-1");
947         needcomma=true;
948         continue;
949       }
950       ClassDescriptor cd=arraycd.getSuperDesc();
951       int level=arraytd.getArrayCount()-1;
952       int type=-1;
953       for(; level>0; level--) {
954         TypeDescriptor supertd=new TypeDescriptor(objectclass);
955         supertd.setArrayCount(level);
956         type=state.getArrayNumber(supertd);
957         if (type!=-1) {
958           type+=state.numClasses();
959           break;
960         }
961       }
962       if (needcomma)
963         outclassdefs.print(", ");
964       outclassdefs.print(type);
965       needcomma=true;
966     }
967
968     outclassdefs.println("};");
969   }
970
971   /** Constructs params and temp objects for each method or task.
972    * These objects tell the compiler which temps need to be
973    * allocated.  */
974
975   protected void generateTempStructs(FlatMethod fm, LocalityBinding lb) {
976     MethodDescriptor md=fm.getMethod();
977     TaskDescriptor task=fm.getTask();
978     Set<TempDescriptor> saveset=lb!=null ? locality.getTempSet(lb) : null;
979     ParamsObject objectparams=md!=null ? new ParamsObject(md,tag++) : new ParamsObject(task, tag++);
980     if (lb!=null) {
981       paramstable.put(lb, objectparams);
982       backuptable.put(lb, new Hashtable<TempDescriptor, TempDescriptor>());
983     } else if (md!=null)
984       paramstable.put(md, objectparams);
985     else
986       paramstable.put(task, objectparams);
987
988     for(int i=0; i<fm.numParameters(); i++) {
989       TempDescriptor temp=fm.getParameter(i);
990       TypeDescriptor type=temp.getType();
991       if (type.isPtr()&&GENERATEPRECISEGC)
992         objectparams.addPtr(temp);
993       else
994         objectparams.addPrim(temp);
995       if(lb!=null&&saveset.contains(temp)) {
996         backuptable.get(lb).put(temp, temp.createNew());
997       }
998     }
999
1000     for(int i=0; i<fm.numTags(); i++) {
1001       TempDescriptor temp=fm.getTag(i);
1002       if (GENERATEPRECISEGC)
1003         objectparams.addPtr(temp);
1004       else
1005         objectparams.addPrim(temp);
1006     }
1007
1008     TempObject objecttemps=md!=null ? new TempObject(objectparams,md,tag++) : new TempObject(objectparams, task, tag++);
1009     if (lb!=null)
1010       tempstable.put(lb, objecttemps);
1011     else if (md!=null)
1012       tempstable.put(md, objecttemps);
1013     else
1014       tempstable.put(task, objecttemps);
1015
1016     for(Iterator nodeit=fm.getNodeSet().iterator(); nodeit.hasNext();) {
1017       FlatNode fn=(FlatNode)nodeit.next();
1018       TempDescriptor[] writes=fn.writesTemps();
1019       for(int i=0; i<writes.length; i++) {
1020         TempDescriptor temp=writes[i];
1021         TypeDescriptor type=temp.getType();
1022         if (type.isPtr()&&GENERATEPRECISEGC)
1023           objecttemps.addPtr(temp);
1024         else
1025           objecttemps.addPrim(temp);
1026         if(lb!=null&&saveset.contains(temp)&&
1027            !backuptable.get(lb).containsKey(temp))
1028           backuptable.get(lb).put(temp, temp.createNew());
1029       }
1030     }
1031
1032     /* Create backup temps */
1033     if (lb!=null) {
1034       for(Iterator<TempDescriptor> tmpit=backuptable.get(lb).values().iterator(); tmpit.hasNext();) {
1035         TempDescriptor tmp=tmpit.next();
1036         TypeDescriptor type=tmp.getType();
1037         if (type.isPtr()&&GENERATEPRECISEGC)
1038           objecttemps.addPtr(tmp);
1039         else
1040           objecttemps.addPrim(tmp);
1041       }
1042       /* Create temp to hold revert table */
1043       if (state.DSM&&(lb.getHasAtomic()||lb.isAtomic())) {
1044         TempDescriptor reverttmp=new TempDescriptor("revertlist", typeutil.getClass(TypeUtil.ObjectClass));
1045         if (GENERATEPRECISEGC)
1046           objecttemps.addPtr(reverttmp);
1047         else
1048           objecttemps.addPrim(reverttmp);
1049         reverttable.put(lb, reverttmp);
1050       }
1051     }
1052   }
1053
1054   /** This method outputs the following information about classes
1055    * and arrays:
1056    * (1) For classes, what are the locations of pointers.
1057    * (2) For arrays, does the array contain pointers or primitives.
1058    * (3) For classes, does the class contain flags.
1059    */
1060
1061   private void generateLayoutStructs(PrintWriter output) {
1062     Iterator it=state.getClassSymbolTable().getDescriptorsIterator();
1063     while(it.hasNext()) {
1064       ClassDescriptor cn=(ClassDescriptor)it.next();
1065       output.println("unsigned INTPTR "+cn.getSafeSymbol()+"_pointers[]={");
1066       Iterator allit=cn.getFieldTable().getAllDescriptorsIterator();
1067       int count=0;
1068       while(allit.hasNext()) {
1069         FieldDescriptor fd=(FieldDescriptor)allit.next();
1070         TypeDescriptor type=fd.getType();
1071         if (state.DSM&&fd.isGlobal())         //Don't GC the global objects for now
1072           continue;
1073         if (type.isPtr())
1074           count++;
1075       }
1076       output.print(count);
1077       allit=cn.getFieldTable().getAllDescriptorsIterator();
1078       while(allit.hasNext()) {
1079         FieldDescriptor fd=(FieldDescriptor)allit.next();
1080         TypeDescriptor type=fd.getType();
1081         if (state.DSM&&fd.isGlobal())         //Don't GC the global objects for now
1082           continue;
1083         if (type.isPtr()) {
1084           output.println(",");
1085           output.print("((unsigned INTPTR)&(((struct "+cn.getSafeSymbol() +" *)0)->"+fd.getSafeSymbol()+"))");
1086         }
1087       }
1088       output.println("};");
1089     }
1090     output.println("unsigned INTPTR * pointerarray[]={");
1091     boolean needcomma=false;
1092     for(int i=0; i<state.numClasses(); i++) {
1093       ClassDescriptor cn=cdarray[i];
1094       if (needcomma)
1095         output.println(",");
1096       needcomma=true;
1097       output.print(cn.getSafeSymbol()+"_pointers");
1098     }
1099
1100     for(int i=0; i<state.numArrays(); i++) {
1101       if (needcomma)
1102         output.println(", ");
1103       TypeDescriptor tdelement=arraytable[i].dereference();
1104       if (tdelement.isArray()||tdelement.isClass())
1105         output.print("((unsigned INTPTR *)1)");
1106       else
1107         output.print("0");
1108       needcomma=true;
1109     }
1110
1111     output.println("};");
1112     needcomma=false;
1113     output.println("int hasflags[]={");
1114     for(int i=0; i<state.numClasses(); i++) {
1115       ClassDescriptor cn=cdarray[i];
1116       if (needcomma)
1117         output.println(", ");
1118       needcomma=true;
1119       if (cn.hasFlags())
1120         output.print("1");
1121       else
1122         output.print("0");
1123     }
1124     output.println("};");
1125   }
1126
1127   /** Print out table to give us supertypes */
1128   private void generateSuperTypeTable(PrintWriter output) {
1129     output.println("int supertypes[]={");
1130     boolean needcomma=false;
1131     for(int i=0; i<state.numClasses(); i++) {
1132       ClassDescriptor cn=cdarray[i];
1133       if (needcomma)
1134         output.println(",");
1135       needcomma=true;
1136       if (cn.getSuperDesc()!=null) {
1137         ClassDescriptor cdsuper=cn.getSuperDesc();
1138         output.print(cdsuper.getId());
1139       } else
1140         output.print("-1");
1141     }
1142     output.println("};");
1143   }
1144
1145   /** Force consistent field ordering between inherited classes. */
1146
1147   private void printClassStruct(ClassDescriptor cn, PrintWriter classdefout) {
1148
1149     ClassDescriptor sp=cn.getSuperDesc();
1150     if (sp!=null)
1151       printClassStruct(sp, classdefout);
1152
1153     if (!fieldorder.containsKey(cn)) {
1154       Vector fields=new Vector();
1155       fieldorder.put(cn,fields);
1156       if (sp==null&&!state.TASK) {
1157         fields.add(cn.getFieldTable().get("cachedCode"));
1158       }
1159       Iterator fieldit=cn.getFields();
1160       while(fieldit.hasNext()) {
1161         FieldDescriptor fd=(FieldDescriptor)fieldit.next();
1162         if ((sp==null||!sp.getFieldTable().contains(fd.getSymbol()))&&
1163             (!fd.getSymbol().equals("cachedCode")||state.TASK))
1164           fields.add(fd);
1165       }
1166     }
1167     Vector fields=(Vector)fieldorder.get(cn);
1168
1169     for(int i=0; i<fields.size(); i++) {
1170       FieldDescriptor fd=(FieldDescriptor)fields.get(i);
1171       if (fd.getType().isClass()||fd.getType().isArray())
1172         classdefout.println("  struct "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
1173       else
1174         classdefout.println("  "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
1175     }
1176   }
1177
1178
1179   /* Map flags to integers consistently between inherited
1180    * classes. */
1181
1182   protected void mapFlags(ClassDescriptor cn) {
1183     ClassDescriptor sp=cn.getSuperDesc();
1184     if (sp!=null)
1185       mapFlags(sp);
1186     int max=0;
1187     if (!flagorder.containsKey(cn)) {
1188       Hashtable flags=new Hashtable();
1189       flagorder.put(cn,flags);
1190       if (sp!=null) {
1191         Hashtable superflags=(Hashtable)flagorder.get(sp);
1192         Iterator superflagit=superflags.keySet().iterator();
1193         while(superflagit.hasNext()) {
1194           FlagDescriptor fd=(FlagDescriptor)superflagit.next();
1195           Integer number=(Integer)superflags.get(fd);
1196           flags.put(fd, number);
1197           if ((number.intValue()+1)>max)
1198             max=number.intValue()+1;
1199         }
1200       }
1201
1202       Iterator flagit=cn.getFlags();
1203       while(flagit.hasNext()) {
1204         FlagDescriptor fd=(FlagDescriptor)flagit.next();
1205         if (sp==null||!sp.getFlagTable().contains(fd.getSymbol()))
1206           flags.put(fd, new Integer(max++));
1207       }
1208     }
1209   }
1210
1211
1212   /** This function outputs (1) structures that parameters are
1213    * passed in (when PRECISE GC is enabled) and (2) function
1214    * prototypes for the methods */
1215
1216   protected void generateCallStructs(ClassDescriptor cn, PrintWriter classdefout, PrintWriter output, PrintWriter headersout) {
1217     /* Output class structure */
1218     classdefout.println("struct "+cn.getSafeSymbol()+" {");
1219     classdefout.println("  int type;");
1220     if (state.THREAD) {
1221       classdefout.println("  pthread_t tid;");
1222       classdefout.println("  void * lockentry;");
1223       classdefout.println("  int lockcount;");
1224     }
1225
1226     if (state.TASK) {
1227       classdefout.println("  int flag;");
1228       if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) {
1229         classdefout.println("  void * flagptr;");
1230       } else if (state.MULTICORE) {
1231         classdefout.println("  int isolate;");        // indicate if this object is shared or not
1232         classdefout.println("  int version;");
1233         classdefout.println("  struct ___Object___ * original;");
1234         //classdefout.println("  int numlocks;");        // array for locks
1235         classdefout.println("  int * lock;");
1236       }
1237       if (state.OPTIONAL) {
1238         classdefout.println("  int numfses;");
1239         classdefout.println("  int * fses;");
1240       }
1241     }
1242     printClassStruct(cn, classdefout);
1243     classdefout.println("};\n");
1244
1245     if (state.DSM||state.SINGLETM) {
1246       /* Cycle through LocalityBindings */
1247       HashSet<MethodDescriptor> nativemethods=new HashSet<MethodDescriptor>();
1248       Set<LocalityBinding> lbset=locality.getClassBindings(cn);
1249       if (lbset!=null) {
1250         for(Iterator<LocalityBinding> lbit=lbset.iterator(); lbit.hasNext();) {
1251           LocalityBinding lb=lbit.next();
1252           MethodDescriptor md=lb.getMethod();
1253           if (md.getModifiers().isNative()) {
1254             //make sure we only print a native method once
1255             if (nativemethods.contains(md)) {
1256               FlatMethod fm=state.getMethodFlat(md);
1257               generateTempStructs(fm, lb);
1258               continue;
1259             } else
1260               nativemethods.add(md);
1261           }
1262           generateMethod(cn, md, lb, headersout, output);
1263         }
1264       }
1265       for(Iterator methodit=cn.getMethods(); methodit.hasNext();) {
1266         MethodDescriptor md=(MethodDescriptor)methodit.next();
1267         if (md.getModifiers().isNative()&&!nativemethods.contains(md)) {
1268           //Need to build param structure for library code
1269           FlatMethod fm=state.getMethodFlat(md);
1270           generateTempStructs(fm, null);
1271           generateMethodParam(cn, md, null, output);
1272         }
1273       }
1274
1275     } else
1276       for(Iterator methodit=cn.getMethods(); methodit.hasNext();) {
1277         MethodDescriptor md=(MethodDescriptor)methodit.next();
1278         generateMethod(cn, md, null, headersout, output);
1279       }
1280   }
1281
1282   private void generateMethodParam(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter output) {
1283     /* Output parameter structure */
1284     if (GENERATEPRECISEGC) {
1285       ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null ? lb : md);
1286       if ((state.DSM||state.SINGLETM)&&lb!=null)
1287         output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
1288       else
1289         output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params {");
1290       output.println("  INTPTR size;");
1291       output.println("  void * next;");
1292       for(int i=0; i<objectparams.numPointers(); i++) {
1293         TempDescriptor temp=objectparams.getPointer(i);
1294         output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1295       }
1296       output.println("};\n");
1297     }
1298   }
1299
1300
1301   private void generateMethod(ClassDescriptor cn, MethodDescriptor md, LocalityBinding lb, PrintWriter headersout, PrintWriter output) {
1302     FlatMethod fm=state.getMethodFlat(md);
1303     generateTempStructs(fm, lb);
1304
1305     ParamsObject objectparams=(ParamsObject) paramstable.get(lb!=null ? lb : md);
1306     TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md);
1307
1308     generateMethodParam(cn, md, lb, output);
1309
1310     /* Output temp structure */
1311     if (GENERATEPRECISEGC) {
1312       if (state.DSM||state.SINGLETM)
1313         output.println("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
1314       else
1315         output.println("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals {");
1316       output.println("  INTPTR size;");
1317       output.println("  void * next;");
1318       for(int i=0; i<objecttemps.numPointers(); i++) {
1319         TempDescriptor temp=objecttemps.getPointer(i);
1320         if (temp.getType().isNull())
1321           output.println("  void * "+temp.getSafeSymbol()+";");
1322         else
1323           output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1324       }
1325       output.println("};\n");
1326     }
1327
1328     /********* Output method declaration ***********/
1329     if (state.DSM||state.SINGLETM) {
1330       headersout.println("#define D"+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+" 1");
1331     } else {
1332       headersout.println("#define D"+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+" 1");
1333     }
1334     /* First the return type */
1335     if (md.getReturnType()!=null) {
1336       if (md.getReturnType().isClass()||md.getReturnType().isArray())
1337         headersout.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
1338       else
1339         headersout.print(md.getReturnType().getSafeSymbol()+" ");
1340     } else
1341       //catch the constructor case
1342       headersout.print("void ");
1343
1344     /* Next the method name */
1345     if (state.DSM||state.SINGLETM) {
1346       headersout.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1347     } else {
1348       headersout.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
1349     }
1350     boolean printcomma=false;
1351     if (GENERATEPRECISEGC) {
1352       if (state.DSM||state.SINGLETM) {
1353         headersout.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1354       } else
1355         headersout.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
1356       printcomma=true;
1357     }
1358
1359     /*  Output parameter list*/
1360     for(int i=0; i<objectparams.numPrimitives(); i++) {
1361       TempDescriptor temp=objectparams.getPrimitive(i);
1362       if (printcomma)
1363         headersout.print(", ");
1364       printcomma=true;
1365       if (temp.getType().isClass()||temp.getType().isArray())
1366         headersout.print("struct " + temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
1367       else
1368         headersout.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
1369     }
1370     headersout.println(");\n");
1371   }
1372
1373
1374   /** This function outputs (1) structures that parameters are
1375    * passed in (when PRECISE GC is enabled) and (2) function
1376    * prototypes for the tasks */
1377
1378   private void generateTaskStructs(PrintWriter output, PrintWriter headersout) {
1379     /* Cycle through tasks */
1380     Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
1381
1382     while(taskit.hasNext()) {
1383       /* Classify parameters */
1384       TaskDescriptor task=(TaskDescriptor)taskit.next();
1385       FlatMethod fm=state.getMethodFlat(task);
1386       generateTempStructs(fm, null);
1387
1388       ParamsObject objectparams=(ParamsObject) paramstable.get(task);
1389       TempObject objecttemps=(TempObject) tempstable.get(task);
1390
1391       /* Output parameter structure */
1392       if (GENERATEPRECISEGC) {
1393         output.println("struct "+task.getSafeSymbol()+"_params {");
1394
1395         output.println("  INTPTR size;");
1396         output.println("  void * next;");
1397         for(int i=0; i<objectparams.numPointers(); i++) {
1398           TempDescriptor temp=objectparams.getPointer(i);
1399           output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1400         }
1401
1402         output.println("};\n");
1403         if ((objectparams.numPointers()+fm.numTags())>maxtaskparams) {
1404           maxtaskparams=objectparams.numPointers()+fm.numTags();
1405         }
1406       }
1407
1408       /* Output temp structure */
1409       if (GENERATEPRECISEGC) {
1410         output.println("struct "+task.getSafeSymbol()+"_locals {");
1411         output.println("  INTPTR size;");
1412         output.println("  void * next;");
1413         for(int i=0; i<objecttemps.numPointers(); i++) {
1414           TempDescriptor temp=objecttemps.getPointer(i);
1415           if (temp.getType().isNull())
1416             output.println("  void * "+temp.getSafeSymbol()+";");
1417           else if(temp.getType().isTag())
1418             output.println("  struct "+
1419                            (new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1420           else
1421             output.println("  struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+";");
1422         }
1423         output.println("};\n");
1424       }
1425
1426       /* Output task declaration */
1427       headersout.print("void " + task.getSafeSymbol()+"(");
1428
1429       boolean printcomma=false;
1430       if (GENERATEPRECISEGC) {
1431         headersout.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
1432       } else
1433         headersout.print("void * parameterarray[]");
1434       headersout.println(");\n");
1435     }
1436   }
1437
1438   /***** Generate code for FlatMethod fm. *****/
1439
1440   private void generateFlatMethod(FlatMethod fm, LocalityBinding lb, PrintWriter output) {
1441     if (State.PRINTFLAT)
1442       System.out.println(fm.printMethod());
1443     MethodDescriptor md=fm.getMethod();
1444
1445     TaskDescriptor task=fm.getTask();
1446
1447     ClassDescriptor cn=md!=null ? md.getClassDesc() : null;
1448
1449     ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : md!=null ? md : task);
1450     generateHeader(fm, lb, md!=null ? md : task,output);
1451     TempObject objecttemp=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
1452
1453     if (GENERATEPRECISEGC) {
1454       if (md!=null&&(state.DSM||state.SINGLETM))
1455         output.print("   struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1456       else if (md!=null&&!(state.DSM||state.SINGLETM))
1457         output.print("   struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_locals "+localsprefix+"={");
1458       else
1459         output.print("   struct "+task.getSafeSymbol()+"_locals "+localsprefix+"={");
1460
1461       output.print(objecttemp.numPointers()+",");
1462       output.print(paramsprefix);
1463       for(int j=0; j<objecttemp.numPointers(); j++)
1464         output.print(", NULL");
1465       output.println("};");
1466     }
1467
1468     for(int i=0; i<objecttemp.numPrimitives(); i++) {
1469       TempDescriptor td=objecttemp.getPrimitive(i);
1470       TypeDescriptor type=td.getType();
1471       if (type.isNull())
1472         output.println("   void * "+td.getSafeSymbol()+";");
1473       else if (type.isClass()||type.isArray())
1474         output.println("   struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
1475       else
1476         output.println("   "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
1477     }
1478
1479     /* Check to see if we need to do a GC if this is a
1480      * multi-threaded program...*/
1481
1482     if ((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC) {
1483       //Don't bother if we aren't in recursive methods...The loops case will catch it
1484       if (callgraph.getAllMethods(md).contains(md)) {
1485         if (state.DSM&&lb.isAtomic())
1486           output.println("if (needtocollect) checkcollect2(&"+localsprefix+");");
1487         else
1488           output.println("if (needtocollect) checkcollect(&"+localsprefix+");");
1489       }
1490     }
1491
1492     generateCode(fm.getNext(0), fm, lb, null, output);
1493
1494     output.println("}\n\n");
1495   }
1496
1497
1498   protected void generateMethodSESE(FlatSESEEnterNode fsen,
1499                                     FlatMethod fm,
1500                                     LocalityBinding lb,
1501                                     PrintWriter output) {
1502
1503     //output.println( "void _SESE"+fsen.getPrettyIdentifier()+
1504     //" {\n" );
1505     //generateCode( fsen.getNext(0), fm, lb, fsen.getFlatExit(), output );
1506     //output.println( "}\n\n" );
1507
1508     /*
1509        output.println("struct sese"+faen.getPrettyIdentifier()+"in {");
1510        Iterator<TempDescriptor> itr = faen.getInVarSet().iterator();
1511        while( itr.hasNext() ) {
1512        TempDescriptor td = itr.next();
1513        output.println("  "+td+";");
1514        }
1515        output.println("}");
1516
1517        output.println("struct sese"+faen.getPrettyIdentifier()+"out {");
1518        itr = faen.getOutVarSet().iterator();
1519        while( itr.hasNext() ) {
1520        TempDescriptor td = itr.next();
1521        output.println("  "+td+";");
1522        }
1523        output.println("}");
1524      */
1525
1526   }
1527
1528
1529   protected void generateCode(FlatNode first,
1530                               FlatMethod fm,
1531                               LocalityBinding lb,
1532                               FlatSESEExitNode stop,
1533                               PrintWriter output) {
1534
1535     /* Assign labels to FlatNode's if necessary.*/
1536     Hashtable<FlatNode, Integer> nodetolabel=assignLabels(first);
1537
1538     /* Do the actual code generation */
1539     FlatNode current_node=null;
1540     HashSet tovisit=new HashSet();
1541     HashSet visited=new HashSet();
1542     tovisit.add(first);
1543     while(current_node!=null||!tovisit.isEmpty()) {
1544       if (current_node==null) {
1545         current_node=(FlatNode)tovisit.iterator().next();
1546         tovisit.remove(current_node);
1547       } else if (tovisit.contains(current_node)) {
1548         tovisit.remove(current_node);
1549       }
1550       if(current_node==stop) {
1551         return;
1552       }
1553       visited.add(current_node);
1554       if (nodetolabel.containsKey(current_node))
1555         output.println("L"+nodetolabel.get(current_node)+":");
1556       if (state.INSTRUCTIONFAILURE) {
1557         if (state.THREAD||state.DSM||state.SINGLETM) {
1558           output.println("if ((++instructioncount)>failurecount) {instructioncount=0;injectinstructionfailure();}");
1559         } else
1560           output.println("if ((--instructioncount)==0) injectinstructionfailure();");
1561       }
1562       if (current_node.numNext()==0) {
1563         output.print("   ");
1564         generateFlatNode(fm, lb, current_node, output);
1565         if (current_node.kind()!=FKind.FlatReturnNode) {
1566           output.println("   return;");
1567         }
1568         current_node=null;
1569       } else if(current_node.numNext()==1) {
1570         FlatNode nextnode;
1571         if (state.MLP && current_node.kind()==FKind.FlatSESEEnterNode) {
1572           FlatSESEEnterNode fsen = (FlatSESEEnterNode)current_node;
1573           if( nonSESEpass ) {
1574             setSESEtoGen.add(fsen);
1575             fsen.setEnclosingFlatMeth(fm);
1576           }
1577           nextnode=fsen.getFlatExit().getNext(0);
1578         } else {
1579           output.print("   ");
1580           generateFlatNode(fm, lb, current_node, output);
1581           nextnode=current_node.getNext(0);
1582         }
1583         if (visited.contains(nextnode)) {
1584           output.println("goto L"+nodetolabel.get(nextnode)+";");
1585           current_node=null;
1586         } else
1587           current_node=nextnode;
1588       } else if (current_node.numNext()==2) {
1589         /* Branch */
1590         output.print("   ");
1591         generateFlatCondBranch(fm, lb, (FlatCondBranch)current_node, "L"+nodetolabel.get(current_node.getNext(1)), output);
1592         if (!visited.contains(current_node.getNext(1)))
1593           tovisit.add(current_node.getNext(1));
1594         if (visited.contains(current_node.getNext(0))) {
1595           output.println("goto L"+nodetolabel.get(current_node.getNext(0))+";");
1596           current_node=null;
1597         } else
1598           current_node=current_node.getNext(0);
1599       } else throw new Error();
1600     }
1601   }
1602
1603
1604   /** This method assigns labels to FlatNodes */
1605
1606   protected Hashtable<FlatNode, Integer> assignLabels(FlatNode first) {
1607     HashSet tovisit=new HashSet();
1608     HashSet visited=new HashSet();
1609     int labelindex=0;
1610     Hashtable<FlatNode, Integer> nodetolabel=new Hashtable<FlatNode, Integer>();
1611     tovisit.add(first);
1612
1613     /*Assign labels first.  A node needs a label if the previous
1614      * node has two exits or this node is a join point. */
1615
1616     while(!tovisit.isEmpty()) {
1617       FlatNode fn=(FlatNode)tovisit.iterator().next();
1618       tovisit.remove(fn);
1619       visited.add(fn);
1620       for(int i=0; i<fn.numNext(); i++) {
1621         FlatNode nn=fn.getNext(i);
1622         if(i>0) {
1623           //1) Edge >1 of node
1624           nodetolabel.put(nn,new Integer(labelindex++));
1625         }
1626         if (!visited.contains(nn)&&!tovisit.contains(nn)) {
1627           tovisit.add(nn);
1628         } else {
1629           //2) Join point
1630           nodetolabel.put(nn,new Integer(labelindex++));
1631         }
1632       }
1633     }
1634     return nodetolabel;
1635   }
1636
1637
1638   /** Generate text string that corresponds to the TempDescriptor td. */
1639   protected String generateTemp(FlatMethod fm, TempDescriptor td, LocalityBinding lb) {
1640     MethodDescriptor md=fm.getMethod();
1641     TaskDescriptor task=fm.getTask();
1642     TempObject objecttemps=(TempObject) tempstable.get(lb!=null ? lb : md!=null ? md : task);
1643     if (objecttemps.isLocalPrim(td)||objecttemps.isParamPrim(td)) {
1644       //System.out.println("generateTemp returns " + td.getSafeSymbol());
1645       return td.getSafeSymbol();
1646     }
1647
1648     if (objecttemps.isLocalPtr(td)) {
1649       return localsprefix+"."+td.getSafeSymbol();
1650     }
1651
1652     if (objecttemps.isParamPtr(td)) {
1653       return paramsprefix+"->"+td.getSafeSymbol();
1654     }
1655     throw new Error();
1656   }
1657
1658   protected void generateFlatNode(FlatMethod fm, LocalityBinding lb, FlatNode fn, PrintWriter output) {
1659     switch(fn.kind()) {
1660     case FKind.FlatAtomicEnterNode:
1661       generateFlatAtomicEnterNode(fm, lb, (FlatAtomicEnterNode) fn, output);
1662       return;
1663
1664     case FKind.FlatAtomicExitNode:
1665       generateFlatAtomicExitNode(fm, lb, (FlatAtomicExitNode) fn, output);
1666       return;
1667
1668     case FKind.FlatInstanceOfNode:
1669       generateFlatInstanceOfNode(fm, lb, (FlatInstanceOfNode)fn, output);
1670       return;
1671
1672     case FKind.FlatSESEEnterNode:
1673       assert !state.MLP;
1674       return;
1675
1676     case FKind.FlatSESEExitNode:
1677       assert !state.MLP;
1678       return;
1679
1680     case FKind.FlatGlobalConvNode:
1681       generateFlatGlobalConvNode(fm, lb, (FlatGlobalConvNode) fn, output);
1682       return;
1683
1684     case FKind.FlatTagDeclaration:
1685       generateFlatTagDeclaration(fm, lb, (FlatTagDeclaration) fn,output);
1686       return;
1687
1688     case FKind.FlatCall:
1689       generateFlatCall(fm, lb, (FlatCall) fn,output);
1690       return;
1691
1692     case FKind.FlatFieldNode:
1693       generateFlatFieldNode(fm, lb, (FlatFieldNode) fn,output);
1694       return;
1695
1696     case FKind.FlatElementNode:
1697       generateFlatElementNode(fm, lb, (FlatElementNode) fn,output);
1698       return;
1699
1700     case FKind.FlatSetElementNode:
1701       generateFlatSetElementNode(fm, lb, (FlatSetElementNode) fn,output);
1702       return;
1703
1704     case FKind.FlatSetFieldNode:
1705       generateFlatSetFieldNode(fm, lb, (FlatSetFieldNode) fn,output);
1706       return;
1707
1708     case FKind.FlatNew:
1709       generateFlatNew(fm, lb, (FlatNew) fn,output);
1710       return;
1711
1712     case FKind.FlatOpNode:
1713       generateFlatOpNode(fm, lb, (FlatOpNode) fn,output);
1714       return;
1715
1716     case FKind.FlatCastNode:
1717       generateFlatCastNode(fm, lb, (FlatCastNode) fn,output);
1718       return;
1719
1720     case FKind.FlatLiteralNode:
1721       generateFlatLiteralNode(fm, lb, (FlatLiteralNode) fn,output);
1722       return;
1723
1724     case FKind.FlatReturnNode:
1725       generateFlatReturnNode(fm, lb, (FlatReturnNode) fn,output);
1726       return;
1727
1728     case FKind.FlatNop:
1729       output.println("/* nop */");
1730       return;
1731
1732     case FKind.FlatExit:
1733       output.println("/* exit */");
1734       return;
1735
1736     case FKind.FlatBackEdge:
1737       if ((state.THREAD||state.DSM||state.SINGLETM)&&GENERATEPRECISEGC) {
1738         if(state.DSM&&locality.getAtomic(lb).get(fn).intValue()>0) {
1739           output.println("if (needtocollect) checkcollect2(&"+localsprefix+");");
1740         } else
1741           output.println("if (needtocollect) checkcollect(&"+localsprefix+");");
1742       } else
1743         output.println("/* nop */");
1744       return;
1745
1746     case FKind.FlatCheckNode:
1747       generateFlatCheckNode(fm, lb, (FlatCheckNode) fn, output);
1748       return;
1749
1750     case FKind.FlatFlagActionNode:
1751       generateFlatFlagActionNode(fm, lb, (FlatFlagActionNode) fn, output);
1752       return;
1753
1754     case FKind.FlatPrefetchNode:
1755       generateFlatPrefetchNode(fm,lb, (FlatPrefetchNode) fn, output);
1756       return;
1757
1758     case FKind.FlatOffsetNode:
1759       generateFlatOffsetNode(fm, lb, (FlatOffsetNode)fn, output);
1760       return;
1761     }
1762     throw new Error();
1763   }
1764
1765   public void generateFlatOffsetNode(FlatMethod fm, LocalityBinding lb, FlatOffsetNode fofn, PrintWriter output) {
1766     output.println("/* FlatOffsetNode */");
1767     FieldDescriptor fd=fofn.getField();
1768     output.println(generateTemp(fm, fofn.getDst(),lb)+ " = (short)(int) (&((struct "+fofn.getClassType().getSafeSymbol() +" *)0)->"+ fd.getSafeSymbol()+");");
1769     output.println("/* offset */");
1770   }
1771
1772   public void generateFlatPrefetchNode(FlatMethod fm, LocalityBinding lb, FlatPrefetchNode fpn, PrintWriter output) {
1773     if (state.PREFETCH) {
1774       Vector oids = new Vector();
1775       Vector fieldoffset = new Vector();
1776       Vector endoffset = new Vector();
1777       int tuplecount = 0;        //Keeps track of number of prefetch tuples that need to be generated
1778       for(Iterator it = fpn.hspp.iterator(); it.hasNext();) {
1779         PrefetchPair pp = (PrefetchPair) it.next();
1780         Integer statusbase = locality.getNodePreTempInfo(lb,fpn).get(pp.base);
1781         /* Find prefetches that can generate oid */
1782         if(statusbase == LocalityAnalysis.GLOBAL) {
1783           generateTransCode(fm, lb, pp, oids, fieldoffset, endoffset, tuplecount, locality.getAtomic(lb).get(fpn).intValue()>0, false);
1784           tuplecount++;
1785         } else if (statusbase == LocalityAnalysis.LOCAL) {
1786           generateTransCode(fm,lb,pp,oids,fieldoffset,endoffset,tuplecount,false,true);
1787         } else {
1788           continue;
1789         }
1790       }
1791       if (tuplecount==0)
1792         return;
1793       System.out.println("Adding prefetch "+fpn+ " to method:" +fm);
1794       output.println("{");
1795       output.println("/* prefetch */");
1796       output.println("/* prefetchid_" + fpn.siteid + " */");
1797       output.println("void * prefptr;");
1798       output.println("int tmpindex;");
1799
1800       output.println("if((evalPrefetch["+fpn.siteid+"].operMode) || (evalPrefetch["+fpn.siteid+"].retrycount <= 0)) {");
1801       /*Create C code for oid array */
1802       output.print("   unsigned int oidarray_[] = {");
1803       boolean needcomma=false;
1804       for (Iterator it = oids.iterator(); it.hasNext();) {
1805         if (needcomma)
1806           output.print(", ");
1807         output.print(it.next());
1808         needcomma=true;
1809       }
1810       output.println("};");
1811
1812       /*Create C code for endoffset values */
1813       output.print("   unsigned short endoffsetarry_[] = {");
1814       needcomma=false;
1815       for (Iterator it = endoffset.iterator(); it.hasNext();) {
1816         if (needcomma)
1817           output.print(", ");
1818         output.print(it.next());
1819         needcomma=true;
1820       }
1821       output.println("};");
1822
1823       /*Create C code for Field Offset Values */
1824       output.print("   short fieldarry_[] = {");
1825       needcomma=false;
1826       for (Iterator it = fieldoffset.iterator(); it.hasNext();) {
1827         if (needcomma)
1828           output.print(", ");
1829         output.print(it.next());
1830         needcomma=true;
1831       }
1832       output.println("};");
1833       /* make the prefetch call to Runtime */
1834       output.println("   if(!evalPrefetch["+fpn.siteid+"].operMode) {");
1835       output.println("     evalPrefetch["+fpn.siteid+"].retrycount = RETRYINTERVAL;");
1836       output.println("   }");
1837       output.println("   prefetch("+fpn.siteid+" ,"+tuplecount+", oidarray_, endoffsetarry_, fieldarry_);");
1838       output.println(" } else {");
1839       output.println("   evalPrefetch["+fpn.siteid+"].retrycount--;");
1840       output.println(" }");
1841       output.println("}");
1842     }
1843   }
1844
1845   public void generateTransCode(FlatMethod fm, LocalityBinding lb,PrefetchPair pp, Vector oids, Vector fieldoffset, Vector endoffset, int tuplecount, boolean inside, boolean localbase) {
1846     short offsetcount = 0;
1847     int breakindex=0;
1848     if (inside) {
1849       breakindex=1;
1850     } else if (localbase) {
1851       for(; breakindex<pp.desc.size(); breakindex++) {
1852         Descriptor desc=pp.getDescAt(breakindex);
1853         if (desc instanceof FieldDescriptor) {
1854           FieldDescriptor fd=(FieldDescriptor)desc;
1855           if (fd.isGlobal()) {
1856             break;
1857           }
1858         }
1859       }
1860       breakindex++;
1861     }
1862
1863     if (breakindex>pp.desc.size())     //all local
1864       return;
1865
1866     TypeDescriptor lasttype=pp.base.getType();
1867     String basestr=generateTemp(fm, pp.base, lb);
1868     String teststr="";
1869     boolean maybenull=fm.getMethod().isStatic()||
1870                        !pp.base.equals(fm.getParameter(0));
1871
1872     for(int i=0; i<breakindex; i++) {
1873       String indexcheck="";
1874
1875       Descriptor desc=pp.getDescAt(i);
1876       if (desc instanceof FieldDescriptor) {
1877         FieldDescriptor fd=(FieldDescriptor)desc;
1878         if (maybenull) {
1879           if (!teststr.equals(""))
1880             teststr+="&&";
1881           teststr+="((prefptr="+basestr+")!=NULL)";
1882           basestr="((struct "+lasttype.getSafeSymbol()+" *)prefptr)->"+fd.getSafeSymbol();
1883         } else {
1884           basestr=basestr+"->"+fd.getSafeSymbol();
1885           maybenull=true;
1886         }
1887         lasttype=fd.getType();
1888       } else {
1889         IndexDescriptor id=(IndexDescriptor)desc;
1890         indexcheck="((tmpindex=";
1891         for(int j=0; j<id.tddesc.size(); j++) {
1892           indexcheck+=generateTemp(fm, id.getTempDescAt(j), lb)+"+";
1893         }
1894         indexcheck+=id.offset+")>=0)&(tmpindex<((struct ArrayObject *)prefptr)->___length___)";
1895
1896         if (!teststr.equals(""))
1897           teststr+="&&";
1898         teststr+="((prefptr="+basestr+")!= NULL) &&"+indexcheck;
1899         basestr="((void **)(((char *) &(((struct ArrayObject *)prefptr)->___length___))+sizeof(int)))[tmpindex]";
1900         maybenull=true;
1901         lasttype=lasttype.dereference();
1902       }
1903     }
1904
1905     String oid;
1906     if (teststr.equals("")) {
1907       oid="((unsigned int)"+basestr+")";
1908     } else {
1909       oid="((unsigned int)(("+teststr+")?"+basestr+":NULL))";
1910     }
1911     oids.add(oid);
1912
1913     for(int i = breakindex; i < pp.desc.size(); i++) {
1914       String newfieldoffset;
1915       Object desc = pp.getDescAt(i);
1916       if(desc instanceof FieldDescriptor) {
1917         FieldDescriptor fd=(FieldDescriptor)desc;
1918         newfieldoffset = new String("(unsigned int)(&(((struct "+ lasttype.getSafeSymbol()+" *)0)->"+ fd.getSafeSymbol()+ "))");
1919         lasttype=fd.getType();
1920       } else {
1921         newfieldoffset = "";
1922         IndexDescriptor id=(IndexDescriptor)desc;
1923         for(int j = 0; j < id.tddesc.size(); j++) {
1924           newfieldoffset += generateTemp(fm, id.getTempDescAt(j), lb) + "+";
1925         }
1926         newfieldoffset += id.offset.toString();
1927         lasttype=lasttype.dereference();
1928       }
1929       fieldoffset.add(newfieldoffset);
1930     }
1931
1932     int base=(tuplecount>0) ? ((Short)endoffset.get(tuplecount-1)).intValue() : 0;
1933     base+=pp.desc.size()-breakindex;
1934     endoffset.add(new Short((short)base));
1935   }
1936
1937
1938
1939   public void generateFlatGlobalConvNode(FlatMethod fm, LocalityBinding lb, FlatGlobalConvNode fgcn, PrintWriter output) {
1940     if (lb!=fgcn.getLocality())
1941       return;
1942     /* Have to generate flat globalconv */
1943     if (fgcn.getMakePtr()) {
1944       if (state.DSM) {
1945         output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", (unsigned int) "+generateTemp(fm, fgcn.getSrc(),lb)+");");
1946       } else {
1947         output.println("TRANSREAD("+generateTemp(fm, fgcn.getSrc(),lb)+", "+generateTemp(fm, fgcn.getSrc(),lb)+");");
1948       }
1949     } else {
1950       /* Need to convert to OID */
1951       if (fgcn.doConvert()) {
1952         output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=(void *)COMPOID("+generateTemp(fm, fgcn.getSrc(),lb)+");");
1953       } else {
1954         output.println(generateTemp(fm, fgcn.getSrc(),lb)+"=NULL;");
1955       }
1956     }
1957   }
1958
1959   public void generateFlatInstanceOfNode(FlatMethod fm,  LocalityBinding lb, FlatInstanceOfNode fion, PrintWriter output) {
1960     int type;
1961     if (fion.getType().isArray()) {
1962       type=state.getArrayNumber(fion.getType())+state.numClasses();
1963     } else {
1964       type=fion.getType().getClassDesc().getId();
1965     }
1966
1967     if (fion.getType().getSymbol().equals(TypeUtil.ObjectClass))
1968       output.println(generateTemp(fm, fion.getDst(), lb)+"=1;");
1969     else
1970       output.println(generateTemp(fm, fion.getDst(), lb)+"=instanceof("+generateTemp(fm,fion.getSrc(),lb)+","+type+");");
1971   }
1972
1973   public void generateFlatAtomicEnterNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicEnterNode faen, PrintWriter output) {
1974     /* Check to see if we need to generate code for this atomic */
1975     if (locality==null||locality.getAtomic(lb).get(faen.getPrev(0)).intValue()>0)
1976       return;
1977     /* Backup the temps. */
1978     for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator(); tmpit.hasNext();) {
1979       TempDescriptor tmp=tmpit.next();
1980       output.println(generateTemp(fm, backuptable.get(lb).get(tmp),lb)+"="+generateTemp(fm,tmp,lb)+";");
1981     }
1982
1983     output.println("goto transstart"+faen.getIdentifier()+";");
1984
1985     /******* Print code to retry aborted transaction *******/
1986     output.println("transretry"+faen.getIdentifier()+":");
1987
1988     /* Restore temps */
1989     for(Iterator<TempDescriptor> tmpit=locality.getTemps(lb).get(faen).iterator(); tmpit.hasNext();) {
1990       TempDescriptor tmp=tmpit.next();
1991       output.println(generateTemp(fm, tmp,lb)+"="+generateTemp(fm,backuptable.get(lb).get(tmp),lb)+";");
1992     }
1993
1994     if (state.DSM) {
1995       /********* Need to revert local object store ********/
1996       String revertptr=generateTemp(fm, reverttable.get(lb),lb);
1997
1998       output.println("while ("+revertptr+") {");
1999       output.println("struct ___Object___ * tmpptr;");
2000       output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
2001       output.println("REVERT_OBJ("+revertptr+");");
2002       output.println(revertptr+"=tmpptr;");
2003       output.println("}");
2004     }
2005     /******* Tell the runtime to start the transaction *******/
2006
2007     output.println("transstart"+faen.getIdentifier()+":");
2008     output.println("transStart();");
2009
2010     if (state.ABORTREADERS) {
2011       output.println("if (_setjmp(aborttrans)) {");
2012       output.println("  goto transretry"+faen.getIdentifier()+"; }");
2013     }
2014   }
2015
2016   public void generateFlatAtomicExitNode(FlatMethod fm,  LocalityBinding lb, FlatAtomicExitNode faen, PrintWriter output) {
2017     /* Check to see if we need to generate code for this atomic */
2018     if (locality==null||locality.getAtomic(lb).get(faen).intValue()>0)
2019       return;
2020     //store the revert list before we lose the transaction object
2021     String revertptr=null;
2022     if (state.DSM) {
2023       revertptr=generateTemp(fm, reverttable.get(lb),lb);
2024       output.println(revertptr+"=revertlist;");
2025     }
2026     output.println("if (transCommit()) {");
2027     /* Transaction aborts if it returns true */
2028     output.println("goto transretry"+faen.getAtomicEnter().getIdentifier()+";");
2029     if (state.DSM) {
2030       output.println("} else {");
2031       /* Need to commit local object store */
2032       output.println("while ("+revertptr+") {");
2033       output.println("struct ___Object___ * tmpptr;");
2034       output.println("tmpptr="+revertptr+"->"+nextobjstr+";");
2035       output.println("COMMIT_OBJ("+revertptr+");");
2036       output.println(revertptr+"=tmpptr;");
2037       output.println("}");
2038     }
2039     output.println("}");
2040   }
2041
2042
2043   public void generateSESE(FlatMethod fm, LocalityBinding lb, FlatSESEEnterNode faen, PrintWriter output) {
2044
2045   }
2046
2047
2048   public void generateFlatSESEEnterNode(FlatMethod fm,  LocalityBinding lb, FlatSESEEnterNode faen, PrintWriter output) {
2049   }
2050
2051   public void generateFlatSESEExitNode(FlatMethod fm,  LocalityBinding lb, FlatSESEExitNode faen, PrintWriter output) {
2052     //output.println("mlpNotifyExit( (struct SESE*)0 );");
2053   }
2054
2055   private void generateFlatCheckNode(FlatMethod fm,  LocalityBinding lb, FlatCheckNode fcn, PrintWriter output) {
2056     if (state.CONSCHECK) {
2057       String specname=fcn.getSpec();
2058       String varname="repairstate___";
2059       output.println("{");
2060       output.println("struct "+specname+"_state * "+varname+"=allocate"+specname+"_state();");
2061
2062       TempDescriptor[] temps=fcn.getTemps();
2063       String[] vars=fcn.getVars();
2064       for(int i=0; i<temps.length; i++) {
2065         output.println(varname+"->"+vars[i]+"=(unsigned int)"+generateTemp(fm, temps[i],lb)+";");
2066       }
2067
2068       output.println("if (doanalysis"+specname+"("+varname+")) {");
2069       output.println("free"+specname+"_state("+varname+");");
2070       output.println("} else {");
2071       output.println("/* Bad invariant */");
2072       output.println("free"+specname+"_state("+varname+");");
2073       output.println("abort_task();");
2074       output.println("}");
2075       output.println("}");
2076     }
2077   }
2078
2079   private void generateFlatCall(FlatMethod fm, LocalityBinding lb, FlatCall fc, PrintWriter output) {
2080     MethodDescriptor md=fc.getMethod();
2081     ParamsObject objectparams=(ParamsObject)paramstable.get(state.DSM||state.SINGLETM ? locality.getBinding(lb, fc) : md);
2082     ClassDescriptor cn=md.getClassDesc();
2083     output.println("{");
2084     if (GENERATEPRECISEGC) {
2085       if (state.DSM||state.SINGLETM) {
2086         LocalityBinding fclb=locality.getBinding(lb, fc);
2087         output.print("       struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
2088       } else
2089         output.print("       struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params __parameterlist__={");
2090
2091       output.print(objectparams.numPointers());
2092       output.print(", & "+localsprefix);
2093       if (md.getThis()!=null) {
2094         output.print(", ");
2095         output.print("(struct "+md.getThis().getType().getSafeSymbol() +" *)"+ generateTemp(fm,fc.getThis(),lb));
2096       }
2097       if (fc.getThis()!=null&&md.getThis()==null) {
2098         System.out.println("WARNING!!!!!!!!!!!!");
2099         System.out.println("Source code calls static method "+md+" on an object in "+fm.getMethod()+"!");
2100       }
2101
2102
2103       for(int i=0; i<fc.numArgs(); i++) {
2104         Descriptor var=md.getParameter(i);
2105         TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
2106         if (objectparams.isParamPtr(paramtemp)) {
2107           TempDescriptor targ=fc.getArg(i);
2108           output.print(", ");
2109           TypeDescriptor td=md.getParamType(i);
2110           if (td.isTag())
2111             output.print("(struct "+(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass))).getSafeSymbol()  +" *)"+generateTemp(fm, targ,lb));
2112           else
2113             output.print("(struct "+md.getParamType(i).getSafeSymbol()  +" *)"+generateTemp(fm, targ,lb));
2114         }
2115       }
2116       output.println("};");
2117     }
2118     output.print("       ");
2119
2120
2121     if (fc.getReturnTemp()!=null)
2122       output.print(generateTemp(fm,fc.getReturnTemp(),lb)+"=");
2123
2124     /* Do we need to do virtual dispatch? */
2125     if (md.isStatic()||md.getReturnType()==null||singleCall(fc.getThis().getType().getClassDesc(),md)) {
2126       //no
2127       if (state.DSM||state.SINGLETM) {
2128         LocalityBinding fclb=locality.getBinding(lb, fc);
2129         output.print(cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
2130       } else {
2131         output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor());
2132       }
2133     } else {
2134       //yes
2135       output.print("((");
2136       if (md.getReturnType().isClass()||md.getReturnType().isArray())
2137         output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
2138       else
2139         output.print(md.getReturnType().getSafeSymbol()+" ");
2140       output.print("(*)(");
2141
2142       boolean printcomma=false;
2143       if (GENERATEPRECISEGC) {
2144         if (state.DSM||state.SINGLETM) {
2145           LocalityBinding fclb=locality.getBinding(lb, fc);
2146           output.print("struct "+cn.getSafeSymbol()+fclb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
2147         } else
2148           output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * ");
2149         printcomma=true;
2150       }
2151
2152       for(int i=0; i<objectparams.numPrimitives(); i++) {
2153         TempDescriptor temp=objectparams.getPrimitive(i);
2154         if (printcomma)
2155           output.print(", ");
2156         printcomma=true;
2157         if (temp.getType().isClass()||temp.getType().isArray())
2158           output.print("struct " + temp.getType().getSafeSymbol()+" * ");
2159         else
2160           output.print(temp.getType().getSafeSymbol());
2161       }
2162
2163
2164       if (state.DSM||state.SINGLETM) {
2165         LocalityBinding fclb=locality.getBinding(lb, fc);
2166         output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getLocalityNumber(fclb)+"])");
2167       } else
2168         output.print("))virtualtable["+generateTemp(fm,fc.getThis(),lb)+"->type*"+maxcount+"+"+virtualcalls.getMethodNumber(md)+"])");
2169     }
2170
2171     output.print("(");
2172     boolean needcomma=false;
2173     if (GENERATEPRECISEGC) {
2174       output.print("&__parameterlist__");
2175       needcomma=true;
2176     }
2177
2178     if (!GENERATEPRECISEGC) {
2179       if (fc.getThis()!=null) {
2180         TypeDescriptor ptd=md.getThis().getType();
2181         if (needcomma)
2182           output.print(",");
2183         if (ptd.isClass()&&!ptd.isArray())
2184           output.print("(struct "+ptd.getSafeSymbol()+" *) ");
2185         output.print(generateTemp(fm,fc.getThis(),lb));
2186         needcomma=true;
2187       }
2188     }
2189
2190     for(int i=0; i<fc.numArgs(); i++) {
2191       Descriptor var=md.getParameter(i);
2192       TempDescriptor paramtemp=(TempDescriptor)temptovar.get(var);
2193       if (objectparams.isParamPrim(paramtemp)) {
2194         TempDescriptor targ=fc.getArg(i);
2195         if (needcomma)
2196           output.print(", ");
2197
2198         TypeDescriptor ptd=md.getParamType(i);
2199         if (ptd.isClass()&&!ptd.isArray())
2200           output.print("(struct "+ptd.getSafeSymbol()+" *) ");
2201         output.print(generateTemp(fm, targ,lb));
2202         needcomma=true;
2203       }
2204     }
2205     output.println(");");
2206     output.println("   }");
2207   }
2208
2209   private boolean singleCall(ClassDescriptor thiscd, MethodDescriptor md) {
2210     Set subclasses=typeutil.getSubClasses(thiscd);
2211     if (subclasses==null)
2212       return true;
2213     for(Iterator classit=subclasses.iterator(); classit.hasNext();) {
2214       ClassDescriptor cd=(ClassDescriptor)classit.next();
2215       Set possiblematches=cd.getMethodTable().getSet(md.getSymbol());
2216       for(Iterator matchit=possiblematches.iterator(); matchit.hasNext();) {
2217         MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
2218         if (md.matches(matchmd))
2219           return false;
2220       }
2221     }
2222     return true;
2223   }
2224
2225   private void generateFlatFieldNode(FlatMethod fm, LocalityBinding lb, FlatFieldNode ffn, PrintWriter output) {
2226     if (state.SINGLETM) {
2227       //single machine transactional memory case
2228       String field=ffn.getField().getSafeSymbol();
2229       String src=generateTemp(fm, ffn.getSrc(),lb);
2230       String dst=generateTemp(fm, ffn.getDst(),lb);
2231
2232       output.println(dst+"="+ src +"->"+field+ ";");
2233       if (ffn.getField().getType().isPtr()&&locality.getAtomic(lb).get(ffn).intValue()>0&&
2234           ((dc==null)||dc.getNeedTrans(lb, ffn))&&
2235           locality.getNodePreTempInfo(lb, ffn).get(ffn.getSrc())!=LocalityAnalysis.SCRATCH) {
2236         output.println("TRANSREAD("+dst+", "+dst+");");
2237       }
2238     } else if (state.DSM) {
2239       Integer status=locality.getNodePreTempInfo(lb,ffn).get(ffn.getSrc());
2240       if (status==LocalityAnalysis.GLOBAL) {
2241         String field=ffn.getField().getSafeSymbol();
2242         String src=generateTemp(fm, ffn.getSrc(),lb);
2243         String dst=generateTemp(fm, ffn.getDst(),lb);
2244
2245         if (ffn.getField().getType().isPtr()) {
2246
2247           //TODO: Uncomment this when we have runtime support
2248           //if (ffn.getSrc()==ffn.getDst()) {
2249           //output.println("{");
2250           //output.println("void * temp="+src+";");
2251           //output.println("if (temp&0x1) {");
2252           //output.println("temp=(void *) transRead(trans, (unsigned int) temp);");
2253           //output.println(src+"->"+field+"="+temp+";");
2254           //output.println("}");
2255           //output.println(dst+"=temp;");
2256           //output.println("}");
2257           //} else {
2258           output.println(dst+"="+ src +"->"+field+ ";");
2259           //output.println("if ("+dst+"&0x1) {");
2260           output.println("TRANSREAD("+dst+", (unsigned int) "+dst+");");
2261           //output.println(src+"->"+field+"="+src+"->"+field+";");
2262           //output.println("}");
2263           //}
2264         } else {
2265           output.println(dst+"="+ src+"->"+field+";");
2266         }
2267       } else if (status==LocalityAnalysis.LOCAL) {
2268         if (ffn.getField().getType().isPtr()&&
2269             ffn.getField().isGlobal()) {
2270           String field=ffn.getField().getSafeSymbol();
2271           String src=generateTemp(fm, ffn.getSrc(),lb);
2272           String dst=generateTemp(fm, ffn.getDst(),lb);
2273           output.println(dst+"="+ src +"->"+field+ ";");
2274           if (locality.getAtomic(lb).get(ffn).intValue()>0)
2275             output.println("TRANSREAD("+dst+", (unsigned int) "+dst+");");
2276         } else
2277           output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
2278       } else if (status==LocalityAnalysis.EITHER) {
2279         //Code is reading from a null pointer
2280         output.println("if ("+generateTemp(fm, ffn.getSrc(),lb)+") {");
2281         output.println("#ifndef RAW");
2282         output.println("printf(\"BIG ERROR\\n\");exit(-1);}");
2283         output.println("#endif");
2284         //This should throw a suitable null pointer error
2285         output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
2286       } else
2287         throw new Error("Read from non-global/non-local in:"+lb.getExplanation());
2288     } else
2289       output.println(generateTemp(fm, ffn.getDst(),lb)+"="+ generateTemp(fm,ffn.getSrc(),lb)+"->"+ ffn.getField().getSafeSymbol()+";");
2290   }
2291
2292
2293   private void generateFlatSetFieldNode(FlatMethod fm, LocalityBinding lb, FlatSetFieldNode fsfn, PrintWriter output) {
2294     if (fsfn.getField().getSymbol().equals("length")&&fsfn.getDst().getType().isArray())
2295       throw new Error("Can't set array length");
2296     if (state.SINGLETM && locality.getAtomic(lb).get(fsfn).intValue()>0) {
2297       //Single Machine Transaction Case
2298       boolean srcptr=fsfn.getSrc().getType().isPtr();
2299       String src=generateTemp(fm,fsfn.getSrc(),lb);
2300       String dst=generateTemp(fm,fsfn.getDst(),lb);
2301       if (srcptr&&!fsfn.getSrc().getType().isNull()) {
2302         output.println("{");
2303         if ((dc==null)||dc.getNeedSrcTrans(lb, fsfn)&&
2304             locality.getNodePreTempInfo(lb, fsfn).get(fsfn.getSrc())!=LocalityAnalysis.SCRATCH) {
2305           output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
2306         } else {
2307           output.println("INTPTR srcoid=(INTPTR)"+src+";");
2308         }
2309       }
2310       if (wb.needBarrier(fsfn)&&
2311           locality.getNodePreTempInfo(lb, fsfn).get(fsfn.getDst())!=LocalityAnalysis.SCRATCH) {
2312         output.println("*((unsigned int *)&("+dst+"->___objstatus___))|=DIRTY;");
2313       }
2314       if (srcptr&!fsfn.getSrc().getType().isNull()) {
2315         output.println("*((unsigned INTPTR *)&("+dst+"->"+ fsfn.getField().getSafeSymbol()+"))=srcoid;");
2316         output.println("}");
2317       } else {
2318         output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
2319       }
2320     } else if (state.DSM && locality.getAtomic(lb).get(fsfn).intValue()>0) {
2321       Integer statussrc=locality.getNodePreTempInfo(lb,fsfn).get(fsfn.getSrc());
2322       Integer statusdst=locality.getNodeTempInfo(lb).get(fsfn).get(fsfn.getDst());
2323       boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL;
2324
2325       String src=generateTemp(fm,fsfn.getSrc(),lb);
2326       String dst=generateTemp(fm,fsfn.getDst(),lb);
2327       if (srcglobal) {
2328         output.println("{");
2329         output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
2330       }
2331       if (statusdst.equals(LocalityAnalysis.GLOBAL)) {
2332         String glbdst=dst;
2333         //mark it dirty
2334         if (wb.needBarrier(fsfn))
2335           output.println("*((unsigned int *)&("+dst+"->___localcopy___))|=DIRTY;");
2336         if (srcglobal) {
2337           output.println("*((unsigned INTPTR *)&("+glbdst+"->"+ fsfn.getField().getSafeSymbol()+"))=srcoid;");
2338         } else
2339           output.println(glbdst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
2340       } else if (statusdst.equals(LocalityAnalysis.LOCAL)) {
2341         /** Check if we need to copy */
2342         output.println("if(!"+dst+"->"+localcopystr+") {");
2343         /* Link object into list */
2344         String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2345         output.println(revertptr+"=revertlist;");
2346         if (GENERATEPRECISEGC)
2347           output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
2348         else
2349           output.println("COPY_OBJ("+dst+");");
2350         output.println(dst+"->"+nextobjstr+"="+revertptr+";");
2351         output.println("revertlist=(struct ___Object___ *)"+dst+";");
2352         output.println("}");
2353         if (srcglobal)
2354           output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=(void *) srcoid;");
2355         else
2356           output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
2357       } else if (statusdst.equals(LocalityAnalysis.EITHER)) {
2358         //writing to a null...bad
2359         output.println("if ("+dst+") {");
2360         output.println("printf(\"BIG ERROR 2\\n\");exit(-1);}");
2361         if (srcglobal)
2362           output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"=(void *) srcoid;");
2363         else
2364           output.println(dst+"->"+ fsfn.getField().getSafeSymbol()+"="+ src+";");
2365       }
2366       if (srcglobal) {
2367         output.println("}");
2368       }
2369     } else {
2370       if (state.FASTCHECK) {
2371         String dst=generateTemp(fm, fsfn.getDst(),lb);
2372         output.println("if(!"+dst+"->"+localcopystr+") {");
2373         /* Link object into list */
2374         if (GENERATEPRECISEGC)
2375           output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
2376         else
2377           output.println("COPY_OBJ("+dst+");");
2378         output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
2379         output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
2380         output.println("}");
2381       }
2382       output.println(generateTemp(fm, fsfn.getDst(),lb)+"->"+ fsfn.getField().getSafeSymbol()+"="+ generateTemp(fm,fsfn.getSrc(),lb)+";");
2383     }
2384   }
2385
2386   private void generateFlatElementNode(FlatMethod fm, LocalityBinding lb, FlatElementNode fen, PrintWriter output) {
2387     TypeDescriptor elementtype=fen.getSrc().getType().dereference();
2388     String type="";
2389
2390     if (elementtype.isArray()||elementtype.isClass())
2391       type="void *";
2392     else
2393       type=elementtype.getSafeSymbol()+" ";
2394
2395     if (this.state.ARRAYBOUNDARYCHECK && fen.needsBoundsCheck()) {
2396       output.println("if ("+generateTemp(fm, fen.getIndex(),lb)+"< 0 | "+generateTemp(fm, fen.getIndex(),lb)+" >= "+generateTemp(fm,fen.getSrc(),lb) + "->___length___)");
2397       output.println("failedboundschk();");
2398     }
2399     if (state.SINGLETM) {
2400       //Single machine transaction case
2401       String dst=generateTemp(fm, fen.getDst(),lb);
2402       output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2403
2404       if (elementtype.isPtr()&&locality.getAtomic(lb).get(fen).intValue()>0&&
2405           ((dc==null)||dc.getNeedTrans(lb, fen))&&
2406           locality.getNodePreTempInfo(lb, fen).get(fen.getSrc())!=LocalityAnalysis.SCRATCH) {
2407         output.println("TRANSREAD("+dst+", "+dst+");");
2408       }
2409     } else if (state.DSM) {
2410       Integer status=locality.getNodePreTempInfo(lb,fen).get(fen.getSrc());
2411       if (status==LocalityAnalysis.GLOBAL) {
2412         String dst=generateTemp(fm, fen.getDst(),lb);
2413
2414         if (elementtype.isPtr()) {
2415           output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2416           output.println("TRANSREAD("+dst+", "+dst+");");
2417         } else {
2418           output.println(dst +"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2419         }
2420       } else if (status==LocalityAnalysis.LOCAL) {
2421         output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2422       } else if (status==LocalityAnalysis.EITHER) {
2423         //Code is reading from a null pointer
2424         output.println("if ("+generateTemp(fm, fen.getSrc(),lb)+") {");
2425         output.println("#ifndef RAW");
2426         output.println("printf(\"BIG ERROR\\n\");exit(-1);}");
2427         output.println("#endif");
2428         //This should throw a suitable null pointer error
2429         output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2430       } else
2431         throw new Error("Read from non-global/non-local in:"+lb.getExplanation());
2432     } else {
2433       output.println(generateTemp(fm, fen.getDst(),lb)+"=(("+ type+"*)(((char *) &("+ generateTemp(fm,fen.getSrc(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fen.getIndex(),lb)+"];");
2434     }
2435   }
2436
2437   private void generateFlatSetElementNode(FlatMethod fm, LocalityBinding lb, FlatSetElementNode fsen, PrintWriter output) {
2438     //TODO: need dynamic check to make sure this assignment is actually legal
2439     //Because Object[] could actually be something more specific...ie. Integer[]
2440
2441     TypeDescriptor elementtype=fsen.getDst().getType().dereference();
2442     String type="";
2443
2444     if (elementtype.isArray()||elementtype.isClass())
2445       type="void *";
2446     else
2447       type=elementtype.getSafeSymbol()+" ";
2448
2449     if (this.state.ARRAYBOUNDARYCHECK && fsen.needsBoundsCheck()) {
2450       output.println("if ("+generateTemp(fm, fsen.getIndex(),lb)+"< 0 | "+generateTemp(fm, fsen.getIndex(),lb)+" >= "+generateTemp(fm,fsen.getDst(),lb) + "->___length___)");
2451       output.println("failedboundschk();");
2452     }
2453
2454     if (state.SINGLETM && locality.getAtomic(lb).get(fsen).intValue()>0) {
2455       //Transaction set element case
2456       if (wb.needBarrier(fsen)&&
2457           locality.getNodePreTempInfo(lb, fsen).get(fsen.getDst())!=LocalityAnalysis.SCRATCH) {
2458         output.println("*((unsigned int *)&("+generateTemp(fm,fsen.getDst(),lb)+"->___objstatus___))|=DIRTY;");
2459       }
2460       if (fsen.getSrc().getType().isPtr()&&!fsen.getSrc().getType().isNull()) {
2461         output.println("{");
2462         String src=generateTemp(fm, fsen.getSrc(), lb);
2463         if ((dc==null)||dc.getNeedSrcTrans(lb, fsen)&&
2464             locality.getNodePreTempInfo(lb, fsen).get(fsen.getSrc())!=LocalityAnalysis.SCRATCH) {
2465           output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
2466         } else {
2467           output.println("INTPTR srcoid=(INTPTR)"+src+";");
2468         }
2469         output.println("((INTPTR*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]=srcoid;");
2470         output.println("}");
2471       } else {
2472         output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
2473       }
2474     } else if (state.DSM && locality.getAtomic(lb).get(fsen).intValue()>0) {
2475       Integer statussrc=locality.getNodePreTempInfo(lb,fsen).get(fsen.getSrc());
2476       Integer statusdst=locality.getNodePreTempInfo(lb,fsen).get(fsen.getDst());
2477       boolean srcglobal=statussrc==LocalityAnalysis.GLOBAL;
2478       boolean dstglobal=statusdst==LocalityAnalysis.GLOBAL;
2479       boolean dstlocal=statusdst==LocalityAnalysis.LOCAL;
2480
2481       if (dstglobal) {
2482         if (wb.needBarrier(fsen))
2483           output.println("*((unsigned int *)&("+generateTemp(fm,fsen.getDst(),lb)+"->___localcopy___))|=DIRTY;");
2484       } else if (dstlocal) {
2485         /** Check if we need to copy */
2486         String dst=generateTemp(fm, fsen.getDst(),lb);
2487         output.println("if(!"+dst+"->"+localcopystr+") {");
2488         /* Link object into list */
2489         String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2490         output.println(revertptr+"=revertlist;");
2491         if (GENERATEPRECISEGC)
2492           output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
2493         else
2494           output.println("COPY_OBJ("+dst+");");
2495         output.println(dst+"->"+nextobjstr+"="+revertptr+";");
2496         output.println("revertlist=(struct ___Object___ *)"+dst+";");
2497         output.println("}");
2498       } else throw new Error("Unknown array type");
2499       if (srcglobal) {
2500         output.println("{");
2501         String src=generateTemp(fm, fsen.getSrc(), lb);
2502         output.println("INTPTR srcoid=("+src+"!=NULL?((INTPTR)"+src+"->"+oidstr+"):0);");
2503         output.println("((INTPTR*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]=srcoid;");
2504         output.println("}");
2505       } else {
2506         output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
2507       }
2508     } else {
2509       if (state.FASTCHECK) {
2510         String dst=generateTemp(fm, fsen.getDst(),lb);
2511         output.println("if(!"+dst+"->"+localcopystr+") {");
2512         /* Link object into list */
2513         if (GENERATEPRECISEGC)
2514           output.println("COPY_OBJ((struct garbagelist *)&"+localsprefix+",(struct ___Object___ *)"+dst+");");
2515         else
2516           output.println("COPY_OBJ("+dst+");");
2517         output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
2518         output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
2519         output.println("}");
2520       }
2521       output.println("(("+type +"*)(((char *) &("+ generateTemp(fm,fsen.getDst(),lb)+"->___length___))+sizeof(int)))["+generateTemp(fm, fsen.getIndex(),lb)+"]="+generateTemp(fm,fsen.getSrc(),lb)+";");
2522     }
2523   }
2524
2525   protected void generateFlatNew(FlatMethod fm, LocalityBinding lb, FlatNew fn, PrintWriter output) {
2526     if (state.DSM && locality.getAtomic(lb).get(fn).intValue()>0&&!fn.isGlobal()) {
2527       //Stash pointer in case of GC
2528       String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2529       output.println(revertptr+"=revertlist;");
2530     }
2531     if (state.SINGLETM) {
2532       if (fn.getType().isArray()) {
2533         int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
2534         if (locality.getAtomic(lb).get(fn).intValue()>0) {
2535           //inside transaction
2536           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarraytrans(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
2537         } else {
2538           //outside transaction
2539           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
2540         }
2541       } else {
2542         if (locality.getAtomic(lb).get(fn).intValue()>0) {
2543           //inside transaction
2544           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newtrans(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
2545         } else {
2546           //outside transaction
2547           output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
2548         }
2549       }
2550     } else if (fn.getType().isArray()) {
2551       int arrayid=state.getArrayNumber(fn.getType())+state.numClasses();
2552       if (fn.isGlobal()&&(state.DSM||state.SINGLETM)) {
2553         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarrayglobal("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
2554       } else if (GENERATEPRECISEGC) {
2555         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray(&"+localsprefix+", "+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
2556       } else {
2557         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newarray("+arrayid+", "+generateTemp(fm, fn.getSize(),lb)+");");
2558       }
2559     } else {
2560       if (fn.isGlobal()) {
2561         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_newglobal("+fn.getType().getClassDesc().getId()+");");
2562       } else if (GENERATEPRECISEGC) {
2563         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new(&"+localsprefix+", "+fn.getType().getClassDesc().getId()+");");
2564       } else {
2565         output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_new("+fn.getType().getClassDesc().getId()+");");
2566       }
2567     }
2568     if (state.DSM && locality.getAtomic(lb).get(fn).intValue()>0&&!fn.isGlobal()) {
2569       String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2570       String dst=generateTemp(fm,fn.getDst(),lb);
2571       output.println(dst+"->___localcopy___=(struct ___Object___*)1;");
2572       output.println(dst+"->"+nextobjstr+"="+revertptr+";");
2573       output.println("revertlist=(struct ___Object___ *)"+dst+";");
2574     }
2575     if (state.FASTCHECK) {
2576       String dst=generateTemp(fm,fn.getDst(),lb);
2577       output.println(dst+"->___localcopy___=(struct ___Object___*)1;");
2578       output.println(dst+"->"+nextobjstr+"="+fcrevert+";");
2579       output.println(fcrevert+"=(struct ___Object___ *)"+dst+";");
2580     }
2581   }
2582
2583   private void generateFlatTagDeclaration(FlatMethod fm, LocalityBinding lb, FlatTagDeclaration fn, PrintWriter output) {
2584     if (GENERATEPRECISEGC) {
2585       output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag(&"+localsprefix+", "+state.getTagId(fn.getType())+");");
2586     } else {
2587       output.println(generateTemp(fm,fn.getDst(),lb)+"=allocate_tag("+state.getTagId(fn.getType())+");");
2588     }
2589   }
2590
2591   private void generateFlatOpNode(FlatMethod fm, LocalityBinding lb, FlatOpNode fon, PrintWriter output) {
2592     if (fon.getRight()!=null) {
2593       if (fon.getOp().getOp()==Operation.URIGHTSHIFT) {
2594         if (fon.getLeft().getType().isLong())
2595           output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned long long)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+generateTemp(fm,fon.getRight(),lb)+";");
2596         else
2597           output.println(generateTemp(fm, fon.getDest(),lb)+" = ((unsigned int)"+generateTemp(fm, fon.getLeft(),lb)+")>>"+generateTemp(fm,fon.getRight(),lb)+";");
2598
2599       } else
2600         output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+fon.getOp().toString()+generateTemp(fm,fon.getRight(),lb)+";");
2601     } else if (fon.getOp().getOp()==Operation.ASSIGN)
2602       output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
2603     else if (fon.getOp().getOp()==Operation.UNARYPLUS)
2604       output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+";");
2605     else if (fon.getOp().getOp()==Operation.UNARYMINUS)
2606       output.println(generateTemp(fm, fon.getDest(),lb)+" = -"+generateTemp(fm, fon.getLeft(),lb)+";");
2607     else if (fon.getOp().getOp()==Operation.LOGIC_NOT)
2608       output.println(generateTemp(fm, fon.getDest(),lb)+" = !"+generateTemp(fm, fon.getLeft(),lb)+";");
2609     else if (fon.getOp().getOp()==Operation.COMP)
2610       output.println(generateTemp(fm, fon.getDest(),lb)+" = ~"+generateTemp(fm, fon.getLeft(),lb)+";");
2611     else if (fon.getOp().getOp()==Operation.ISAVAILABLE) {
2612       output.println(generateTemp(fm, fon.getDest(),lb)+" = "+generateTemp(fm, fon.getLeft(),lb)+"->fses==NULL;");
2613     } else
2614       output.println(generateTemp(fm, fon.getDest(),lb)+fon.getOp().toString()+generateTemp(fm, fon.getLeft(),lb)+";");
2615   }
2616
2617   private void generateFlatCastNode(FlatMethod fm, LocalityBinding lb, FlatCastNode fcn, PrintWriter output) {
2618     /* TODO: Do type check here */
2619     if (fcn.getType().isArray()) {
2620       throw new Error();
2621     } else if (fcn.getType().isClass())
2622       output.println(generateTemp(fm,fcn.getDst(),lb)+"=(struct "+fcn.getType().getSafeSymbol()+" *)"+generateTemp(fm,fcn.getSrc(),lb)+";");
2623     else
2624       output.println(generateTemp(fm,fcn.getDst(),lb)+"=("+fcn.getType().getSafeSymbol()+")"+generateTemp(fm,fcn.getSrc(),lb)+";");
2625   }
2626
2627   private void generateFlatLiteralNode(FlatMethod fm, LocalityBinding lb, FlatLiteralNode fln, PrintWriter output) {
2628     if (fln.getValue()==null)
2629       output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
2630     else if (fln.getType().getSymbol().equals(TypeUtil.StringClass)) {
2631       if (GENERATEPRECISEGC) {
2632         if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) {
2633           //Stash pointer in case of GC
2634           String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2635           output.println(revertptr+"=revertlist;");
2636         }
2637         output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(&"+localsprefix+", \""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
2638         if (state.DSM && locality.getAtomic(lb).get(fln).intValue()>0) {
2639           //Stash pointer in case of GC
2640           String revertptr=generateTemp(fm, reverttable.get(lb),lb);
2641           output.println("revertlist="+revertptr+";");
2642         }
2643       } else {
2644         output.println(generateTemp(fm, fln.getDst(),lb)+"=NewString(\""+FlatLiteralNode.escapeString((String)fln.getValue())+"\","+((String)fln.getValue()).length()+");");
2645       }
2646     } else if (fln.getType().isBoolean()) {
2647       if (((Boolean)fln.getValue()).booleanValue())
2648         output.println(generateTemp(fm, fln.getDst(),lb)+"=1;");
2649       else
2650         output.println(generateTemp(fm, fln.getDst(),lb)+"=0;");
2651     } else if (fln.getType().isChar()) {
2652       String st=FlatLiteralNode.escapeString(fln.getValue().toString());
2653       output.println(generateTemp(fm, fln.getDst(),lb)+"='"+st+"';");
2654     } else if (fln.getType().isLong()) {
2655       output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+"LL;");
2656     } else
2657       output.println(generateTemp(fm, fln.getDst(),lb)+"="+fln.getValue()+";");
2658   }
2659
2660   protected void generateFlatReturnNode(FlatMethod fm, LocalityBinding lb, FlatReturnNode frn, PrintWriter output) {
2661     if (frn.getReturnTemp()!=null) {
2662       if (frn.getReturnTemp().getType().isPtr())
2663         output.println("return (struct "+fm.getMethod().getReturnType().getSafeSymbol()+"*)"+generateTemp(fm, frn.getReturnTemp(), lb)+";");
2664       else
2665         output.println("return "+generateTemp(fm, frn.getReturnTemp(), lb)+";");
2666     } else {
2667       output.println("return;");
2668     }
2669   }
2670
2671   protected void generateFlatCondBranch(FlatMethod fm, LocalityBinding lb, FlatCondBranch fcb, String label, PrintWriter output) {
2672     output.println("if (!"+generateTemp(fm, fcb.getTest(),lb)+") goto "+label+";");
2673   }
2674
2675   /** This method generates header information for the method or
2676    * task referenced by the Descriptor des. */
2677
2678   private void generateHeader(FlatMethod fm, LocalityBinding lb, Descriptor des, PrintWriter output) {
2679     /* Print header */
2680     ParamsObject objectparams=(ParamsObject)paramstable.get(lb!=null ? lb : des);
2681     MethodDescriptor md=null;
2682     TaskDescriptor task=null;
2683     if (des instanceof MethodDescriptor)
2684       md=(MethodDescriptor) des;
2685     else
2686       task=(TaskDescriptor) des;
2687
2688     ClassDescriptor cn=md!=null ? md.getClassDesc() : null;
2689
2690     if (md!=null&&md.getReturnType()!=null) {
2691       if (md.getReturnType().isClass()||md.getReturnType().isArray())
2692         output.print("struct " + md.getReturnType().getSafeSymbol()+" * ");
2693       else
2694         output.print(md.getReturnType().getSafeSymbol()+" ");
2695     } else
2696       //catch the constructor case
2697       output.print("void ");
2698     if (md!=null) {
2699       if (state.DSM||state.SINGLETM) {
2700         output.print(cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
2701       } else
2702         output.print(cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"(");
2703     } else
2704       output.print(task.getSafeSymbol()+"(");
2705
2706     boolean printcomma=false;
2707     if (GENERATEPRECISEGC) {
2708       if (md!=null) {
2709         if (state.DSM||state.SINGLETM) {
2710           output.print("struct "+cn.getSafeSymbol()+lb.getSignature()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
2711         } else
2712           output.print("struct "+cn.getSafeSymbol()+md.getSafeSymbol()+"_"+md.getSafeMethodDescriptor()+"_params * "+paramsprefix);
2713       } else
2714         output.print("struct "+task.getSafeSymbol()+"_params * "+paramsprefix);
2715       printcomma=true;
2716     }
2717
2718     if (md!=null) {
2719       /* Method */
2720       for(int i=0; i<objectparams.numPrimitives(); i++) {
2721         TempDescriptor temp=objectparams.getPrimitive(i);
2722         if (printcomma)
2723           output.print(", ");
2724         printcomma=true;
2725         if (temp.getType().isClass()||temp.getType().isArray())
2726           output.print("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol());
2727         else
2728           output.print(temp.getType().getSafeSymbol()+" "+temp.getSafeSymbol());
2729       }
2730       output.println(") {");
2731     } else if (!GENERATEPRECISEGC) {
2732       /* Imprecise Task */
2733       output.println("void * parameterarray[]) {");
2734       /* Unpack variables */
2735       for(int i=0; i<objectparams.numPrimitives(); i++) {
2736         TempDescriptor temp=objectparams.getPrimitive(i);
2737         output.println("struct "+temp.getType().getSafeSymbol()+" * "+temp.getSafeSymbol()+"=parameterarray["+i+"];");
2738       }
2739       for(int i=0; i<fm.numTags(); i++) {
2740         TempDescriptor temp=fm.getTag(i);
2741         int offset=i+objectparams.numPrimitives();
2742         output.println("struct ___TagDescriptor___ * "+temp.getSafeSymbol()+"=parameterarray["+offset+"];");
2743       }
2744
2745       if ((objectparams.numPrimitives()+fm.numTags())>maxtaskparams)
2746         maxtaskparams=objectparams.numPrimitives()+fm.numTags();
2747     } else output.println(") {");
2748   }
2749
2750   public void generateFlatFlagActionNode(FlatMethod fm, LocalityBinding lb, FlatFlagActionNode ffan, PrintWriter output) {
2751     output.println("/* FlatFlagActionNode */");
2752
2753
2754     /* Process tag changes */
2755     Relation tagsettable=new Relation();
2756     Relation tagcleartable=new Relation();
2757
2758     Iterator tagsit=ffan.getTempTagPairs();
2759     while (tagsit.hasNext()) {
2760       TempTagPair ttp=(TempTagPair) tagsit.next();
2761       TempDescriptor objtmp=ttp.getTemp();
2762       TagDescriptor tag=ttp.getTag();
2763       TempDescriptor tagtmp=ttp.getTagTemp();
2764       boolean tagstatus=ffan.getTagChange(ttp);
2765       if (tagstatus) {
2766         tagsettable.put(objtmp, tagtmp);
2767       } else {
2768         tagcleartable.put(objtmp, tagtmp);
2769       }
2770     }
2771
2772
2773     Hashtable flagandtable=new Hashtable();
2774     Hashtable flagortable=new Hashtable();
2775
2776     /* Process flag changes */
2777     Iterator flagsit=ffan.getTempFlagPairs();
2778     while(flagsit.hasNext()) {
2779       TempFlagPair tfp=(TempFlagPair)flagsit.next();
2780       TempDescriptor temp=tfp.getTemp();
2781       Hashtable flagtable=(Hashtable)flagorder.get(temp.getType().getClassDesc());
2782       FlagDescriptor flag=tfp.getFlag();
2783       if (flag==null) {
2784         //Newly allocate objects that don't set any flags case
2785         if (flagortable.containsKey(temp)) {
2786           throw new Error();
2787         }
2788         int mask=0;
2789         flagortable.put(temp,new Integer(mask));
2790       } else {
2791         int flagid=1<<((Integer)flagtable.get(flag)).intValue();
2792         boolean flagstatus=ffan.getFlagChange(tfp);
2793         if (flagstatus) {
2794           int mask=0;
2795           if (flagortable.containsKey(temp)) {
2796             mask=((Integer)flagortable.get(temp)).intValue();
2797           }
2798           mask|=flagid;
2799           flagortable.put(temp,new Integer(mask));
2800         } else {
2801           int mask=0xFFFFFFFF;
2802           if (flagandtable.containsKey(temp)) {
2803             mask=((Integer)flagandtable.get(temp)).intValue();
2804           }
2805           mask&=(0xFFFFFFFF^flagid);
2806           flagandtable.put(temp,new Integer(mask));
2807         }
2808       }
2809     }
2810
2811
2812     HashSet flagtagset=new HashSet();
2813     flagtagset.addAll(flagortable.keySet());
2814     flagtagset.addAll(flagandtable.keySet());
2815     flagtagset.addAll(tagsettable.keySet());
2816     flagtagset.addAll(tagcleartable.keySet());
2817
2818     Iterator ftit=flagtagset.iterator();
2819     while(ftit.hasNext()) {
2820       TempDescriptor temp=(TempDescriptor)ftit.next();
2821
2822
2823       Set tagtmps=tagcleartable.get(temp);
2824       if (tagtmps!=null) {
2825         Iterator tagit=tagtmps.iterator();
2826         while(tagit.hasNext()) {
2827           TempDescriptor tagtmp=(TempDescriptor)tagit.next();
2828           if (GENERATEPRECISEGC)
2829             output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
2830           else
2831             output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
2832         }
2833       }
2834
2835       tagtmps=tagsettable.get(temp);
2836       if (tagtmps!=null) {
2837         Iterator tagit=tagtmps.iterator();
2838         while(tagit.hasNext()) {
2839           TempDescriptor tagtmp=(TempDescriptor)tagit.next();
2840           if (GENERATEPRECISEGC)
2841             output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp,lb)+", "+generateTemp(fm,tagtmp,lb)+");");
2842           else
2843             output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp, lb)+", "+generateTemp(fm,tagtmp, lb)+");");
2844         }
2845       }
2846
2847       int ormask=0;
2848       int andmask=0xFFFFFFF;
2849
2850       if (flagortable.containsKey(temp))
2851         ormask=((Integer)flagortable.get(temp)).intValue();
2852       if (flagandtable.containsKey(temp))
2853         andmask=((Integer)flagandtable.get(temp)).intValue();
2854       generateFlagOrAnd(ffan, fm, lb, temp, output, ormask, andmask);
2855       generateObjectDistribute(ffan, fm, lb, temp, output);
2856     }
2857   }
2858
2859   protected void generateFlagOrAnd(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp,
2860                                    PrintWriter output, int ormask, int andmask) {
2861     if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) {
2862       output.println("flagorandinit("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
2863     } else {
2864       output.println("flagorand("+generateTemp(fm, temp, lb)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");");
2865     }
2866   }
2867
2868   protected void generateObjectDistribute(FlatFlagActionNode ffan, FlatMethod fm, LocalityBinding lb, TempDescriptor temp, PrintWriter output) {
2869     output.println("enqueueObject("+generateTemp(fm, temp, lb)+");");
2870   }
2871
2872   void generateOptionalHeader(PrintWriter headers) {
2873
2874     //GENERATE HEADERS
2875     headers.println("#include \"task.h\"\n\n");
2876     headers.println("#ifndef _OPTIONAL_STRUCT_");
2877     headers.println("#define _OPTIONAL_STRUCT_");
2878
2879     //STRUCT PREDICATEMEMBER
2880     headers.println("struct predicatemember{");
2881     headers.println("int type;");
2882     headers.println("int numdnfterms;");
2883     headers.println("int * flags;");
2884     headers.println("int numtags;");
2885     headers.println("int * tags;\n};\n\n");
2886
2887     //STRUCT OPTIONALTASKDESCRIPTOR
2888     headers.println("struct optionaltaskdescriptor{");
2889     headers.println("struct taskdescriptor * task;");
2890     headers.println("int index;");
2891     headers.println("int numenterflags;");
2892     headers.println("int * enterflags;");
2893     headers.println("int numpredicatemembers;");
2894     headers.println("struct predicatemember ** predicatememberarray;");
2895     headers.println("};\n\n");
2896
2897     //STRUCT TASKFAILURE
2898     headers.println("struct taskfailure {");
2899     headers.println("struct taskdescriptor * task;");
2900     headers.println("int index;");
2901     headers.println("int numoptionaltaskdescriptors;");
2902     headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
2903
2904     //STRUCT FSANALYSISWRAPPER
2905     headers.println("struct fsanalysiswrapper{");
2906     headers.println("int  flags;");
2907     headers.println("int numtags;");
2908     headers.println("int * tags;");
2909     headers.println("int numtaskfailures;");
2910     headers.println("struct taskfailure ** taskfailurearray;");
2911     headers.println("int numoptionaltaskdescriptors;");
2912     headers.println("struct optionaltaskdescriptor ** optionaltaskdescriptorarray;\n};\n\n");
2913
2914     //STRUCT CLASSANALYSISWRAPPER
2915     headers.println("struct classanalysiswrapper{");
2916     headers.println("int type;");
2917     headers.println("int numotd;");
2918     headers.println("struct optionaltaskdescriptor ** otdarray;");
2919     headers.println("int numfsanalysiswrappers;");
2920     headers.println("struct fsanalysiswrapper ** fsanalysiswrapperarray;\n};");
2921
2922     headers.println("extern struct classanalysiswrapper * classanalysiswrapperarray[];");
2923
2924     Iterator taskit=state.getTaskSymbolTable().getDescriptorsIterator();
2925     while(taskit.hasNext()) {
2926       TaskDescriptor td=(TaskDescriptor)taskit.next();
2927       headers.println("extern struct taskdescriptor task_"+td.getSafeSymbol()+";");
2928     }
2929
2930   }
2931
2932   //CHECK OVER THIS -- THERE COULD BE SOME ERRORS HERE
2933   int generateOptionalPredicate(Predicate predicate, OptionalTaskDescriptor otd, ClassDescriptor cdtemp, PrintWriter output) {
2934     int predicateindex = 0;
2935     //iterate through the classes concerned by the predicate
2936     Set c_vard = predicate.vardescriptors;
2937     Hashtable<TempDescriptor, Integer> slotnumber=new Hashtable<TempDescriptor, Integer>();
2938     int current_slot=0;
2939
2940     for(Iterator vard_it = c_vard.iterator(); vard_it.hasNext();) {
2941       VarDescriptor vard = (VarDescriptor)vard_it.next();
2942       TypeDescriptor typed = vard.getType();
2943
2944       //generate for flags
2945       HashSet fen_hashset = predicate.flags.get(vard.getSymbol());
2946       output.println("int predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2947       int numberterms=0;
2948       if (fen_hashset!=null) {
2949         for (Iterator fen_it = fen_hashset.iterator(); fen_it.hasNext();) {
2950           FlagExpressionNode fen = (FlagExpressionNode)fen_it.next();
2951           if (fen!=null) {
2952             DNFFlag dflag=fen.getDNF();
2953             numberterms+=dflag.size();
2954
2955             Hashtable flags=(Hashtable)flagorder.get(typed.getClassDesc());
2956
2957             for(int j=0; j<dflag.size(); j++) {
2958               if (j!=0)
2959                 output.println(",");
2960               Vector term=dflag.get(j);
2961               int andmask=0;
2962               int checkmask=0;
2963               for(int k=0; k<term.size(); k++) {
2964                 DNFFlagAtom dfa=(DNFFlagAtom)term.get(k);
2965                 FlagDescriptor fd=dfa.getFlag();
2966                 boolean negated=dfa.getNegated();
2967                 int flagid=1<<((Integer)flags.get(fd)).intValue();
2968                 andmask|=flagid;
2969                 if (!negated)
2970                   checkmask|=flagid;
2971               }
2972               output.print("/*andmask*/0x"+Integer.toHexString(andmask)+", /*checkmask*/0x"+Integer.toHexString(checkmask));
2973             }
2974           }
2975         }
2976       }
2977       output.println("};\n");
2978
2979       //generate for tags
2980       TagExpressionList tagel = predicate.tags.get(vard.getSymbol());
2981       output.println("int predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
2982       int numtags = 0;
2983       if (tagel!=null) {
2984         for(int j=0; j<tagel.numTags(); j++) {
2985           if (j!=0)
2986             output.println(",");
2987           TempDescriptor tmp=tagel.getTemp(j);
2988           if (!slotnumber.containsKey(tmp)) {
2989             Integer slotint=new Integer(current_slot++);
2990             slotnumber.put(tmp,slotint);
2991           }
2992           int slot=slotnumber.get(tmp).intValue();
2993           output.println("/* slot */"+ slot+", /*tagid*/"+state.getTagId(tmp.getTag()));
2994         }
2995         numtags = tagel.numTags();
2996       }
2997       output.println("};");
2998
2999       //store the result into a predicatemember struct
3000       output.println("struct predicatemember predicatemember_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
3001       output.println("/*type*/"+typed.getClassDesc().getId()+",");
3002       output.println("/* number of dnf terms */"+numberterms+",");
3003       output.println("predicateflags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3004       output.println("/* number of tag */"+numtags+",");
3005       output.println("predicatetags_"+predicateindex+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3006       output.println("};\n");
3007       predicateindex++;
3008     }
3009
3010
3011     //generate an array that stores the entire predicate
3012     output.println("struct predicatemember * predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
3013     for( int j = 0; j<predicateindex; j++) {
3014       if( j != predicateindex-1) output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3015       else output.println("&predicatemember_"+j+"_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
3016     }
3017     output.println("};\n");
3018     return predicateindex;
3019   }
3020
3021
3022   void generateOptionalArrays(PrintWriter output, PrintWriter headers, Hashtable<ClassDescriptor, Hashtable<FlagState, Set<OptionalTaskDescriptor>>> safeexecution, Hashtable optionaltaskdescriptors) {
3023     generateOptionalHeader(headers);
3024     //GENERATE STRUCTS
3025     output.println("#include \"optionalstruct.h\"\n\n");
3026     output.println("#include \"stdlib.h\"\n");
3027
3028     HashSet processedcd = new HashSet();
3029     int maxotd=0;
3030     Enumeration e = safeexecution.keys();
3031     while (e.hasMoreElements()) {
3032       int numotd=0;
3033       //get the class
3034       ClassDescriptor cdtemp=(ClassDescriptor)e.nextElement();
3035       Hashtable flaginfo=(Hashtable)flagorder.get(cdtemp);       //will be used several times
3036
3037       //Generate the struct of optionals
3038       Collection c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
3039       numotd = c_otd.size();
3040       if(maxotd<numotd) maxotd = numotd;
3041       if( !c_otd.isEmpty() ) {
3042         for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();) {
3043           OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
3044
3045           //generate the int arrays for the predicate
3046           Predicate predicate = otd.predicate;
3047           int predicateindex = generateOptionalPredicate(predicate, otd, cdtemp, output);
3048           TreeSet<Integer> fsset=new TreeSet<Integer>();
3049           //iterate through possible FSes corresponding to
3050           //the state when entering
3051
3052           for(Iterator fses = otd.enterflagstates.iterator(); fses.hasNext();) {
3053             FlagState fs = (FlagState)fses.next();
3054             int flagid=0;
3055             for(Iterator flags = fs.getFlags(); flags.hasNext();) {
3056               FlagDescriptor flagd = (FlagDescriptor)flags.next();
3057               int id=1<<((Integer)flaginfo.get(flagd)).intValue();
3058               flagid|=id;
3059             }
3060             fsset.add(new Integer(flagid));
3061             //tag information not needed because tag
3062             //changes are not tolerated.
3063           }
3064
3065           output.println("int enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"[]={");
3066           boolean needcomma=false;
3067           for(Iterator<Integer> it=fsset.iterator(); it.hasNext();) {
3068             if(needcomma)
3069               output.print(", ");
3070             output.println(it.next());
3071           }
3072
3073           output.println("};\n");
3074
3075
3076           //generate optionaltaskdescriptor that actually
3077           //includes exit fses, predicate and the task
3078           //concerned
3079           output.println("struct optionaltaskdescriptor optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+"={");
3080           output.println("&task_"+otd.td.getSafeSymbol()+",");
3081           output.println("/*index*/"+otd.getIndex()+",");
3082           output.println("/*number of enter flags*/"+fsset.size()+",");
3083           output.println("enterflag_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3084           output.println("/*number of members */"+predicateindex+",");
3085           output.println("predicatememberarray_OTD"+otd.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3086           output.println("};\n");
3087         }
3088       } else
3089         continue;
3090       // if there are no optionals, there is no need to build the rest of the struct
3091
3092       output.println("struct optionaltaskdescriptor * otdarray"+cdtemp.getSafeSymbol()+"[]={");
3093       c_otd = ((Hashtable)optionaltaskdescriptors.get(cdtemp)).values();
3094       if( !c_otd.isEmpty() ) {
3095         boolean needcomma=false;
3096         for(Iterator otd_it = c_otd.iterator(); otd_it.hasNext();) {
3097           OptionalTaskDescriptor otd = (OptionalTaskDescriptor)otd_it.next();
3098           if(needcomma)
3099             output.println(",");
3100           needcomma=true;
3101           output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
3102         }
3103       }
3104       output.println("};\n");
3105
3106       //get all the possible flagstates reachable by an object
3107       Hashtable hashtbtemp = safeexecution.get(cdtemp);
3108       int fscounter = 0;
3109       TreeSet fsts=new TreeSet(new FlagComparator(flaginfo));
3110       fsts.addAll(hashtbtemp.keySet());
3111       for(Iterator fsit=fsts.iterator(); fsit.hasNext();) {
3112         FlagState fs = (FlagState)fsit.next();
3113         fscounter++;
3114
3115         //get the set of OptionalTaskDescriptors corresponding
3116         HashSet<OptionalTaskDescriptor> availabletasks = (HashSet<OptionalTaskDescriptor>)hashtbtemp.get(fs);
3117         //iterate through the OptionalTaskDescriptors and
3118         //store the pointers to the optionals struct (see on
3119         //top) into an array
3120
3121         output.println("struct optionaltaskdescriptor * optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[] = {");
3122         for(Iterator<OptionalTaskDescriptor> mos = ordertd(availabletasks).iterator(); mos.hasNext();) {
3123           OptionalTaskDescriptor mm = mos.next();
3124           if(!mos.hasNext())
3125             output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol());
3126           else
3127             output.println("&optionaltaskdescriptor_"+mm.getuid()+"_"+cdtemp.getSafeSymbol()+",");
3128         }
3129
3130         output.println("};\n");
3131
3132         //process flag information (what the flag after failure is) so we know what optionaltaskdescriptors to choose.
3133
3134         int flagid=0;
3135         for(Iterator flags = fs.getFlags(); flags.hasNext();) {
3136           FlagDescriptor flagd = (FlagDescriptor)flags.next();
3137           int id=1<<((Integer)flaginfo.get(flagd)).intValue();
3138           flagid|=id;
3139         }
3140
3141         //process tag information
3142
3143         int tagcounter = 0;
3144         boolean first = true;
3145         Enumeration tag_enum = fs.getTags();
3146         output.println("int tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
3147         while(tag_enum.hasMoreElements()) {
3148           tagcounter++;
3149           TagDescriptor tagd = (TagDescriptor)tag_enum.nextElement();
3150           if(first==true)
3151             first = false;
3152           else
3153             output.println(", ");
3154           output.println("/*tagid*/"+state.getTagId(tagd));
3155         }
3156         output.println("};");
3157
3158         Set<TaskIndex> tiset=sa.getTaskIndex(fs);
3159         for(Iterator<TaskIndex> itti=tiset.iterator(); itti.hasNext();) {
3160           TaskIndex ti=itti.next();
3161           if (ti.isRuntime())
3162             continue;
3163
3164           Set<OptionalTaskDescriptor> otdset=sa.getOptions(fs, ti);
3165
3166           output.print("struct optionaltaskdescriptor * optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array[] = {");
3167           boolean needcomma=false;
3168           for(Iterator<OptionalTaskDescriptor> otdit=ordertd(otdset).iterator(); otdit.hasNext();) {
3169             OptionalTaskDescriptor otd=otdit.next();
3170             if(needcomma)
3171               output.print(", ");
3172             needcomma=true;
3173             output.println("&optionaltaskdescriptor_"+otd.getuid()+"_"+cdtemp.getSafeSymbol());
3174           }
3175           output.println("};");
3176
3177           output.print("struct taskfailure taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+" = {");
3178           output.print("&task_"+ti.getTask().getSafeSymbol()+", ");
3179           output.print(ti.getIndex()+", ");
3180           output.print(otdset.size()+", ");
3181           output.print("optionaltaskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex()+"_array");
3182           output.println("};");
3183         }
3184
3185         tiset=sa.getTaskIndex(fs);
3186         boolean needcomma=false;
3187         int runtimeti=0;
3188         output.println("struct taskfailure * taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+"[]={");
3189         for(Iterator<TaskIndex> itti=tiset.iterator(); itti.hasNext();) {
3190           TaskIndex ti=itti.next();
3191           if (ti.isRuntime()) {
3192             runtimeti++;
3193             continue;
3194           }
3195           if (needcomma)
3196             output.print(", ");
3197           needcomma=true;
3198           output.print("&taskfailure_FS"+fscounter+"_"+ti.getTask().getSafeSymbol()+"_"+ti.getIndex());
3199         }
3200         output.println("};\n");
3201
3202         //Store the result in fsanalysiswrapper
3203
3204         output.println("struct fsanalysiswrapper fsanalysiswrapper_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+"={");
3205         output.println("/*flag*/"+flagid+",");
3206         output.println("/* number of tags*/"+tagcounter+",");
3207         output.println("tags_FS"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
3208         output.println("/* numtask failures */"+(tiset.size()-runtimeti)+",");
3209         output.println("taskfailurearray"+fscounter+"_"+cdtemp.getSafeSymbol()+",");
3210         output.println("/* number of optionaltaskdescriptors */"+availabletasks.size()+",");
3211         output.println("optionaltaskdescriptorarray_FS"+fscounter+"_"+cdtemp.getSafeSymbol());
3212         output.println("};\n");
3213
3214       }
3215
3216       //Build the array of fsanalysiswrappers
3217       output.println("struct fsanalysiswrapper * fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"[] = {");
3218       boolean needcomma=false;
3219       for(int i = 0; i<fscounter; i++) {
3220         if (needcomma) output.print(",");
3221         output.println("&fsanalysiswrapper_FS"+(i+1)+"_"+cdtemp.getSafeSymbol());
3222         needcomma=true;
3223       }
3224       output.println("};");
3225
3226       //Build the classanalysiswrapper referring to the previous array
3227       output.println("struct classanalysiswrapper classanalysiswrapper_"+cdtemp.getSafeSymbol()+"={");
3228       output.println("/*type*/"+cdtemp.getId()+",");
3229       output.println("/*numotd*/"+numotd+",");
3230       output.println("otdarray"+cdtemp.getSafeSymbol()+",");
3231       output.println("/* number of fsanalysiswrappers */"+fscounter+",");
3232       output.println("fsanalysiswrapperarray_"+cdtemp.getSafeSymbol()+"};\n");
3233       processedcd.add(cdtemp);
3234     }
3235
3236     //build an array containing every classes for which code has been build
3237     output.println("struct classanalysiswrapper * classanalysiswrapperarray[]={");
3238     for(int i=0; i<state.numClasses(); i++) {
3239       ClassDescriptor cn=cdarray[i];
3240       if (i>0)
3241         output.print(", ");
3242       if (processedcd.contains(cn))
3243         output.print("&classanalysiswrapper_"+cn.getSafeSymbol());
3244       else
3245         output.print("NULL");
3246     }
3247     output.println("};");
3248
3249     output.println("#define MAXOTD "+maxotd);
3250     headers.println("#endif");
3251   }
3252
3253   public List<OptionalTaskDescriptor> ordertd(Set<OptionalTaskDescriptor> otdset) {
3254     Relation r=new Relation();
3255     for(Iterator<OptionalTaskDescriptor>otdit=otdset.iterator(); otdit.hasNext();) {
3256       OptionalTaskDescriptor otd=otdit.next();
3257       TaskIndex ti=new TaskIndex(otd.td, otd.getIndex());
3258       r.put(ti, otd);
3259     }
3260
3261     LinkedList<OptionalTaskDescriptor> l=new LinkedList<OptionalTaskDescriptor>();
3262     for(Iterator it=r.keySet().iterator(); it.hasNext();) {
3263       Set s=r.get(it.next());
3264       for(Iterator it2=s.iterator(); it2.hasNext();) {
3265         OptionalTaskDescriptor otd=(OptionalTaskDescriptor)it2.next();
3266         l.add(otd);
3267       }
3268     }
3269
3270     return l;
3271   }
3272
3273   protected void outputTransCode(PrintWriter output) {
3274   }
3275 }
3276
3277
3278
3279
3280
3281